reduce locking on folder children
This commit is contained in:
parent
2d9b48d00f
commit
7360950496
|
@ -336,7 +336,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
return _resolveArgs;
|
||||
}
|
||||
set
|
||||
private set
|
||||
{
|
||||
_resolveArgs = value;
|
||||
_resolveArgsInitialized = value != null;
|
||||
|
@ -349,7 +349,17 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <param name="pathInfo">The path info.</param>
|
||||
public void ResetResolveArgs(FileSystemInfo pathInfo)
|
||||
{
|
||||
ResolveArgs = CreateResolveArgs(pathInfo);
|
||||
ResetResolveArgs(CreateResolveArgs(pathInfo));
|
||||
}
|
||||
|
||||
public void ResetResolveArgs()
|
||||
{
|
||||
ResolveArgs = null;
|
||||
}
|
||||
|
||||
public void ResetResolveArgs(ItemResolveArgs args)
|
||||
{
|
||||
ResolveArgs = args;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -887,10 +897,10 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <returns>true if a provider reports we changed</returns>
|
||||
public virtual async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
|
||||
{
|
||||
if (resetResolveArgs)
|
||||
if (resetResolveArgs || ResolveArgs == null)
|
||||
{
|
||||
// Reload this
|
||||
ResolveArgs = null;
|
||||
ResetResolveArgs();
|
||||
}
|
||||
|
||||
// Refresh for the item
|
||||
|
|
|
@ -107,31 +107,36 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
protected void AddChildrenInternal(IEnumerable<BaseItem> children)
|
||||
{
|
||||
foreach (var child in children)
|
||||
lock (ChildrenSyncLock)
|
||||
{
|
||||
AddChildInternal(child);
|
||||
var newChildren = _children.ToList();
|
||||
newChildren.AddRange(children);
|
||||
_children = newChildren;
|
||||
}
|
||||
}
|
||||
protected void AddChildInternal(BaseItem child)
|
||||
{
|
||||
_children.Add(child);
|
||||
lock (ChildrenSyncLock)
|
||||
{
|
||||
var newChildren = _children.ToList();
|
||||
newChildren.Add(child);
|
||||
_children = newChildren;
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveChildrenInternal(IEnumerable<BaseItem> children)
|
||||
{
|
||||
lock (ChildrenSyncLock)
|
||||
{
|
||||
_children = new ConcurrentBag<BaseItem>(_children.Except(children));
|
||||
_children = _children.Except(children).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
protected void ClearChildrenInternal()
|
||||
{
|
||||
BaseItem removed;
|
||||
|
||||
while (_children.TryTake(out removed))
|
||||
lock (ChildrenSyncLock)
|
||||
{
|
||||
|
||||
_children = new List<BaseItem>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,11 +513,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <summary>
|
||||
/// The children
|
||||
/// </summary>
|
||||
private ConcurrentBag<BaseItem> _children;
|
||||
/// <summary>
|
||||
/// The _children initialized
|
||||
/// </summary>
|
||||
private bool _childrenInitialized;
|
||||
private List<BaseItem> _children;
|
||||
/// <summary>
|
||||
/// The _children sync lock
|
||||
/// </summary>
|
||||
|
@ -525,11 +526,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
get
|
||||
{
|
||||
LazyInitializer.EnsureInitialized(ref _children, ref _childrenInitialized, ref ChildrenSyncLock, LoadChildrenInternal);
|
||||
return _children;
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadSavedChildren()
|
||||
{
|
||||
_children = LoadChildrenInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// thread-safe access to the actual children of this folder - without regard to user
|
||||
/// </summary>
|
||||
|
@ -566,16 +571,15 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
private ConcurrentBag<BaseItem> LoadChildrenInternal()
|
||||
private List<BaseItem> LoadChildrenInternal()
|
||||
{
|
||||
return new ConcurrentBag<BaseItem>(LoadChildren());
|
||||
return LoadChildren().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads our children. Validation will occur externally.
|
||||
/// We want this sychronous.
|
||||
/// </summary>
|
||||
/// <returns>ConcurrentBag{BaseItem}.</returns>
|
||||
protected virtual IEnumerable<BaseItem> LoadChildren()
|
||||
{
|
||||
//just load our children from the repo - the library will be validated and maintained in other processes
|
||||
|
@ -698,7 +702,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (currentChildren.TryGetValue(child.Id, out currentChild))
|
||||
{
|
||||
currentChild.ResolveArgs = child.ResolveArgs;
|
||||
currentChild.ResetResolveArgs(child.ResolveArgs);
|
||||
|
||||
//existing item - check if it has changed
|
||||
if (currentChild.HasChanged(child))
|
||||
|
@ -760,12 +764,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
await LibraryManager.CreateItems(newItems, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
foreach (var item in newItems)
|
||||
{
|
||||
_children.Add(item);
|
||||
|
||||
Logger.Debug("** " + item.Name + " Added to library.");
|
||||
}
|
||||
AddChildrenInternal(newItems);
|
||||
|
||||
await ItemRepository.SaveChildren(Id, _children.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
|||
|
||||
if (dbItem != null)
|
||||
{
|
||||
dbItem.ResolveArgs = video.ResolveArgs;
|
||||
dbItem.ResetResolveArgs(video.ResolveArgs);
|
||||
video = dbItem;
|
||||
}
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
if (resetResolveArgs)
|
||||
{
|
||||
// Reload this
|
||||
ResolveArgs = null;
|
||||
ResetResolveArgs();
|
||||
}
|
||||
|
||||
var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
|
|
|
@ -246,7 +246,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
if (dbItem != null)
|
||||
{
|
||||
dbItem.ResolveArgs = video.ResolveArgs;
|
||||
dbItem.ResetResolveArgs(video.ResolveArgs);
|
||||
video = dbItem;
|
||||
}
|
||||
|
||||
|
|
|
@ -1346,7 +1346,16 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>BaseItem.</returns>
|
||||
public BaseItem RetrieveItem(Guid id)
|
||||
{
|
||||
return ItemRepository.RetrieveItem(id);
|
||||
var item = ItemRepository.RetrieveItem(id);
|
||||
|
||||
var folder = item as Folder;
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
folder.LoadSavedChildren();
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <param name="args">The args.</param>
|
||||
public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args)
|
||||
{
|
||||
item.ResolveArgs = args;
|
||||
item.ResetResolveArgs(args);
|
||||
|
||||
// If the resolver didn't specify this
|
||||
if (string.IsNullOrEmpty(item.Path))
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
EventHelper.FireEventIfNotNull(AppStarted, this, EventArgs.Empty, _logger);
|
||||
|
||||
await task.ConfigureAwait(false);
|
||||
await task;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user