diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 18:06:00 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 18:06:00 -0400 |
| commit | 1d62a88fd8147e9c1bf01cac2852b929b1737c17 (patch) | |
| tree | 7fa1e7dd215551ca7e6fdfcf106dfb265500f5aa /Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs | |
| parent | 13dcb5abb1682940a45e83e5a9f7b71289231986 (diff) | |
move classes to portable server project
Diffstat (limited to 'Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs')
| -rw-r--r-- | Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs new file mode 100644 index 000000000..b93410180 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -0,0 +1,165 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Session; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.EntryPoints +{ + class UserDataChangeNotifier : IServerEntryPoint + { + private readonly ISessionManager _sessionManager; + private readonly ILogger _logger; + private readonly IUserDataManager _userDataManager; + private readonly IUserManager _userManager; + + private readonly object _syncLock = new object(); + private ITimer UpdateTimer { get; set; } + private readonly ITimerFactory _timerFactory; + private const int UpdateDuration = 500; + + private readonly Dictionary<Guid, List<IHasUserData>> _changedItems = new Dictionary<Guid, List<IHasUserData>>(); + + public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager, ITimerFactory timerFactory) + { + _userDataManager = userDataManager; + _sessionManager = sessionManager; + _logger = logger; + _userManager = userManager; + _timerFactory = timerFactory; + } + + public void Run() + { + _userDataManager.UserDataSaved += _userDataManager_UserDataSaved; + } + + void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e) + { + if (e.SaveReason == UserDataSaveReason.PlaybackProgress) + { + return; + } + + lock (_syncLock) + { + if (UpdateTimer == null) + { + UpdateTimer = _timerFactory.Create(UpdateTimerCallback, null, UpdateDuration, + Timeout.Infinite); + } + else + { + UpdateTimer.Change(UpdateDuration, Timeout.Infinite); + } + + List<IHasUserData> keys; + + if (!_changedItems.TryGetValue(e.UserId, out keys)) + { + keys = new List<IHasUserData>(); + _changedItems[e.UserId] = keys; + } + + keys.Add(e.Item); + + var baseItem = e.Item as BaseItem; + + // Go up one level for indicators + if (baseItem != null) + { + var parent = baseItem.GetParent(); + + if (parent != null) + { + keys.Add(parent); + } + } + } + } + + private void UpdateTimerCallback(object state) + { + lock (_syncLock) + { + // Remove dupes in case some were saved multiple times + var changes = _changedItems.ToList(); + _changedItems.Clear(); + + var task = SendNotifications(changes, CancellationToken.None); + + if (UpdateTimer != null) + { + UpdateTimer.Dispose(); + UpdateTimer = null; + } + } + } + + private async Task SendNotifications(IEnumerable<KeyValuePair<Guid, List<IHasUserData>>> changes, CancellationToken cancellationToken) + { + foreach (var pair in changes) + { + var userId = pair.Key; + var userSessions = _sessionManager.Sessions + .Where(u => u.ContainsUser(userId) && u.SessionController != null && u.IsActive) + .ToList(); + + if (userSessions.Count > 0) + { + var user = _userManager.GetUserById(userId); + + var dtoList = pair.Value + .DistinctBy(i => i.Id) + .Select(i => + { + var dto = _userDataManager.GetUserDataDto(i, user).Result; + dto.ItemId = i.Id.ToString("N"); + return dto; + }) + .ToList(); + + var info = new UserDataChangeInfo + { + UserId = userId.ToString("N"), + + UserDataList = dtoList + }; + + foreach (var userSession in userSessions) + { + try + { + await userSession.SessionController.SendUserDataChangeInfo(info, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending UserDataChanged message", ex); + } + } + } + + } + } + + public void Dispose() + { + if (UpdateTimer != null) + { + UpdateTimer.Dispose(); + UpdateTimer = null; + } + + _userDataManager.UserDataSaved -= _userDataManager_UserDataSaved; + } + } +} |
