From e2562879d86aafc1063e37bfd353c22309e8e237 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 2 Apr 2013 15:25:16 -0400 Subject: Moved userdata to user manager to resolve concurrency issues. must delete userdata and displaypreferences db files. --- .../Library/UserManager.cs | 74 +++++++++++++++++----- 1 file changed, 59 insertions(+), 15 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/UserManager.cs') diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index b17f2955e..ca3c1fe7c 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -1,5 +1,4 @@ -using System.Collections.Concurrent; -using MediaBrowser.Common.Events; +using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -9,6 +8,7 @@ using MediaBrowser.Model.Connectivity; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; @@ -104,6 +104,8 @@ namespace MediaBrowser.Server.Implementations.Library /// private readonly ConcurrentDictionary> _displayPreferences = new ConcurrentDictionary>(); + private readonly ConcurrentDictionary> _userData = new ConcurrentDictionary>(); + /// /// Initializes a new instance of the class. /// @@ -200,14 +202,15 @@ namespace MediaBrowser.Server.Implementations.Library public async Task SaveDisplayPreferences(Guid userId, Guid displayPreferencesId, DisplayPreferences displayPreferences, CancellationToken cancellationToken) { var key = userId + displayPreferencesId.ToString(); - var newValue = Task.FromResult(displayPreferences); - + try { await Kernel.Instance.DisplayPreferencesRepository.SaveDisplayPreferences(userId, displayPreferencesId, displayPreferences, cancellationToken).ConfigureAwait(false); + var newValue = Task.FromResult(displayPreferences); + // Once it succeeds, put it into the dictionary to make it available to everyone else _displayPreferences.AddOrUpdate(key, newValue, delegate { return newValue; }); } @@ -651,10 +654,10 @@ namespace MediaBrowser.Server.Implementations.Library if (positionTicks.HasValue) { - var data = item.GetUserData(user, true); + var data = await GetUserData(user.Id, item.UserDataId).ConfigureAwait(false); UpdatePlayState(item, data, positionTicks.Value, false); - await SaveUserDataForItem(user, item, data).ConfigureAwait(false); + await SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None).ConfigureAwait(false); } EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs @@ -689,7 +692,7 @@ namespace MediaBrowser.Server.Implementations.Library RemoveNowPlayingItemId(user, clientType, deviceId, deviceName, item); - var data = item.GetUserData(user, true); + var data = await GetUserData(user.Id, item.UserDataId).ConfigureAwait(false); if (positionTicks.HasValue) { @@ -702,7 +705,7 @@ namespace MediaBrowser.Server.Implementations.Library data.Played = true; } - await SaveUserDataForItem(user, item, data).ConfigureAwait(false); + await SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None).ConfigureAwait(false); EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackProgressEventArgs { @@ -763,16 +766,57 @@ namespace MediaBrowser.Server.Implementations.Library } /// - /// Saves user data for an item + /// Saves display preferences for an item /// - /// The user. - /// The item. - /// The data. - public Task SaveUserDataForItem(User user, BaseItem item, UserItemData data) + /// The user id. + /// The user data id. + /// The user data. + /// The cancellation token. + /// Task. + public async Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData, CancellationToken cancellationToken) + { + var key = userId + userDataId.ToString(); + try + { + await Kernel.Instance.UserDataRepository.SaveUserData(userId, userDataId, userData, cancellationToken).ConfigureAwait(false); + + var newValue = Task.FromResult(userData); + + // Once it succeeds, put it into the dictionary to make it available to everyone else + _userData.AddOrUpdate(key, newValue, delegate { return newValue; }); + } + catch (Exception ex) + { + _logger.ErrorException("Error saving user data", ex); + + throw; + } + } + + /// + /// Gets the display preferences. + /// + /// The user id. + /// The user data id. + /// Task{DisplayPreferences}. + public Task GetUserData(Guid userId, Guid userDataId) + { + var key = userId + userDataId.ToString(); + + return _userData.GetOrAdd(key, keyName => RetrieveUserData(userId, userDataId)); + } + + /// + /// Retrieves the display preferences. + /// + /// The user id. + /// The user data id. + /// DisplayPreferences. + private async Task RetrieveUserData(Guid userId, Guid userDataId) { - item.AddOrUpdateUserData(user, data); + var userdata = await Kernel.Instance.UserDataRepository.GetUserData(userId, userDataId).ConfigureAwait(false); - return Kernel.UserDataRepository.SaveUserData(item, CancellationToken.None); + return userdata ?? new UserItemData(); } } } -- cgit v1.2.3