mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	moved user data cache to manager class
This commit is contained in:
		
							parent
							
								
									76faf89aca
								
							
						
					
					
						commit
						9f8a1b30a1
					
				@ -1,7 +1,9 @@
 | 
				
			|||||||
using MediaBrowser.Controller.Entities;
 | 
					using MediaBrowser.Controller.Entities;
 | 
				
			||||||
using MediaBrowser.Controller.Library;
 | 
					using MediaBrowser.Controller.Library;
 | 
				
			||||||
using MediaBrowser.Controller.Persistence;
 | 
					using MediaBrowser.Controller.Persistence;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Logging;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -12,6 +14,15 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public class UserDataManager : IUserDataManager
 | 
					    public class UserDataManager : IUserDataManager
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly ConcurrentDictionary<string, UserItemData> _userData = new ConcurrentDictionary<string, UserItemData>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private readonly ILogger _logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public UserDataManager(ILogManager logManager)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _logger = logManager.GetLogger(GetType().Name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Gets or sets the repository.
 | 
					        /// Gets or sets the repository.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -26,9 +37,42 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
        /// <param name="userData">The user data.</param>
 | 
					        /// <param name="userData">The user data.</param>
 | 
				
			||||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
					        /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
        /// <returns>Task.</returns>
 | 
					        /// <returns>Task.</returns>
 | 
				
			||||||
        public Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
 | 
					        public async Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return Repository.SaveUserData(userId, key, userData, cancellationToken);
 | 
					            if (userData == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("userData");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (cancellationToken == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("cancellationToken");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (userId == Guid.Empty)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("userId");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(key))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("key");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cancellationToken.ThrowIfCancellationRequested();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var newValue = userData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Once it succeeds, put it into the dictionary to make it available to everyone else
 | 
				
			||||||
 | 
					                _userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _logger.ErrorException("Error saving user data", ex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                throw;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
@ -39,7 +83,27 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
        /// <returns>Task{UserItemData}.</returns>
 | 
					        /// <returns>Task{UserItemData}.</returns>
 | 
				
			||||||
        public UserItemData GetUserData(Guid userId, string key)
 | 
					        public UserItemData GetUserData(Guid userId, string key)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return Repository.GetUserData(userId, key);
 | 
					            if (userId == Guid.Empty)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("userId");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(key))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("key");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return _userData.GetOrAdd(GetCacheKey(userId, key), keyName => Repository.GetUserData(userId, key));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Gets the internal key.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="userId">The user id.</param>
 | 
				
			||||||
 | 
					        /// <param name="key">The key.</param>
 | 
				
			||||||
 | 
					        /// <returns>System.String.</returns>
 | 
				
			||||||
 | 
					        private string GetCacheKey(Guid userId, string key)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return userId + key;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,6 @@ using MediaBrowser.Controller.Persistence;
 | 
				
			|||||||
using MediaBrowser.Model.Logging;
 | 
					using MediaBrowser.Model.Logging;
 | 
				
			||||||
using MediaBrowser.Model.Serialization;
 | 
					using MediaBrowser.Model.Serialization;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
@ -16,8 +15,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        private readonly ILogger _logger;
 | 
					        private readonly ILogger _logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly ConcurrentDictionary<string, UserItemData> _userData = new ConcurrentDictionary<string, UserItemData>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
 | 
					        private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private IDbConnection _connection;
 | 
					        private IDbConnection _connection;
 | 
				
			||||||
@ -113,7 +110,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
        /// userId
 | 
					        /// userId
 | 
				
			||||||
        /// or
 | 
					        /// or
 | 
				
			||||||
        /// userDataId</exception>
 | 
					        /// userDataId</exception>
 | 
				
			||||||
        public async Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
 | 
					        public Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (userData == null)
 | 
					            if (userData == null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -132,34 +129,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                throw new ArgumentNullException("key");
 | 
					                throw new ArgumentNullException("key");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cancellationToken.ThrowIfCancellationRequested();
 | 
					            return PersistUserData(userId, key, userData, cancellationToken);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                await PersistUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                var newValue = userData;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Once it succeeds, put it into the dictionary to make it available to everyone else
 | 
					 | 
				
			||||||
                _userData.AddOrUpdate(GetInternalKey(userId, key), newValue, delegate { return newValue; });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            catch (Exception ex)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                _logger.ErrorException("Error saving user data", ex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                throw;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Gets the internal key.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="userId">The user id.</param>
 | 
					 | 
				
			||||||
        /// <param name="key">The key.</param>
 | 
					 | 
				
			||||||
        /// <returns>System.String.</returns>
 | 
					 | 
				
			||||||
        private string GetInternalKey(Guid userId, string key)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return userId + key;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
@ -255,17 +225,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                throw new ArgumentNullException("key");
 | 
					                throw new ArgumentNullException("key");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return _userData.GetOrAdd(GetInternalKey(userId, key), keyName => RetrieveUserData(userId, key));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// Retrieves the user data.
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="userId">The user id.</param>
 | 
					 | 
				
			||||||
        /// <param name="key">The key.</param>
 | 
					 | 
				
			||||||
        /// <returns>Task{UserItemData}.</returns>
 | 
					 | 
				
			||||||
        private UserItemData RetrieveUserData(Guid userId, string key)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            using (var cmd = _connection.CreateCommand())
 | 
					            using (var cmd = _connection.CreateCommand())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                cmd.CommandText = "select rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId";
 | 
					                cmd.CommandText = "select rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId";
 | 
				
			||||||
 | 
				
			|||||||
@ -238,7 +238,7 @@ namespace MediaBrowser.ServerApplication
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var mediaEncoderTask = RegisterMediaEncoder();
 | 
					            var mediaEncoderTask = RegisterMediaEncoder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            UserDataManager = new UserDataManager();
 | 
					            UserDataManager = new UserDataManager(LogManager);
 | 
				
			||||||
            RegisterSingleInstance(UserDataManager);
 | 
					            RegisterSingleInstance(UserDataManager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            UserRepository = await GetUserRepository().ConfigureAwait(false);
 | 
					            UserRepository = await GetUserRepository().ConfigureAwait(false);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user