diff options
3 files changed, 70 insertions, 47 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index f382df0f0..7d965cd3e 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -1,7 +1,9 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Logging; using System; +using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; @@ -12,6 +14,15 @@ namespace MediaBrowser.Server.Implementations.Library /// </summary> 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> /// Gets or sets the repository. /// </summary> @@ -26,9 +37,42 @@ namespace MediaBrowser.Server.Implementations.Library /// <param name="userData">The user data.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <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> @@ -39,7 +83,27 @@ namespace MediaBrowser.Server.Implementations.Library /// <returns>Task{UserItemData}.</returns> 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; } } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 20b3ff251..e58bd2506 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -4,7 +4,6 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; -using System.Collections.Concurrent; using System.Data; using System.IO; using System.Threading; @@ -16,8 +15,6 @@ namespace MediaBrowser.Server.Implementations.Persistence { private readonly ILogger _logger; - private readonly ConcurrentDictionary<string, UserItemData> _userData = new ConcurrentDictionary<string, UserItemData>(); - private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1); private IDbConnection _connection; @@ -113,7 +110,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// userId /// or /// 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) { @@ -132,34 +129,7 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("key"); } - cancellationToken.ThrowIfCancellationRequested(); - - 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; + return PersistUserData(userId, key, userData, cancellationToken); } /// <summary> @@ -255,17 +225,6 @@ namespace MediaBrowser.Server.Implementations.Persistence 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()) { cmd.CommandText = "select rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId"; diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index a61abe474..9e13e548a 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -238,7 +238,7 @@ namespace MediaBrowser.ServerApplication var mediaEncoderTask = RegisterMediaEncoder(); - UserDataManager = new UserDataManager(); + UserDataManager = new UserDataManager(LogManager); RegisterSingleInstance(UserDataManager); UserRepository = await GetUserRepository().ConfigureAwait(false); |
