Ver Fonte

reduce locking on folder children

Luke Pulverenti há 11 anos atrás
pai
commit
7360950496

+ 14 - 4
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -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

+ 23 - 24
MediaBrowser.Controller/Entities/Folder.cs

@@ -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);
 

+ 1 - 1
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -114,7 +114,7 @@ namespace MediaBrowser.Controller.Entities.Movies
 
                 if (dbItem != null)
                 {
-                    dbItem.ResolveArgs = video.ResolveArgs;
+                    dbItem.ResetResolveArgs(video.ResolveArgs);
                     video = dbItem;
                 }
 

+ 1 - 1
MediaBrowser.Controller/Entities/User.cs

@@ -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);

+ 1 - 1
MediaBrowser.Controller/Entities/Video.cs

@@ -246,7 +246,7 @@ namespace MediaBrowser.Controller.Entities
 
                 if (dbItem != null)
                 {
-                    dbItem.ResolveArgs = video.ResolveArgs;
+                    dbItem.ResetResolveArgs(video.ResolveArgs);
                     video = dbItem;
                 }
 

+ 10 - 1
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -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>();

+ 1 - 1
MediaBrowser.Server.Implementations/Library/ResolverHelper.cs

@@ -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))

+ 1 - 1
MediaBrowser.ServerApplication/App.xaml.cs

@@ -95,7 +95,7 @@ namespace MediaBrowser.ServerApplication
 
                 EventHelper.FireEventIfNotNull(AppStarted, this, EventArgs.Empty, _logger);
 
-                await task.ConfigureAwait(false);
+                await task;
             }
             catch (Exception ex)
             {