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