diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/Channels/ChannelManager.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Channels/ChannelManager.cs | 196 |
1 files changed, 170 insertions, 26 deletions
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index e9df5e52c..98e7593cf 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using System.Collections.Concurrent; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; @@ -23,7 +24,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Channels { - public class ChannelManager : IChannelManager + public class ChannelManager : IChannelManager, IDisposable { private IChannel[] _channels; private IChannelFactory[] _factories; @@ -39,6 +40,9 @@ namespace MediaBrowser.Server.Implementations.Channels private readonly IJsonSerializer _jsonSerializer; private readonly ILocalizationManager _localization; + private readonly ConcurrentDictionary<Guid, bool> _refreshedItems = new ConcurrentDictionary<Guid, bool>(); + + private Timer _refreshTimer; public ChannelManager(IUserManager userManager, IDtoService dtoService, ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IUserDataManager userDataManager, IJsonSerializer jsonSerializer, ILocalizationManager localization) { @@ -51,6 +55,8 @@ namespace MediaBrowser.Server.Implementations.Channels _userDataManager = userDataManager; _jsonSerializer = jsonSerializer; _localization = localization; + + _refreshTimer = new Timer(s => _refreshedItems.Clear(), null, TimeSpan.FromHours(3), TimeSpan.FromHours(3)); } private TimeSpan CacheLength @@ -203,8 +209,8 @@ namespace MediaBrowser.Server.Implementations.Channels if (requiresCallback != null) { - results = await requiresCallback.GetChannelItemMediaInfo(item.ExternalId, cancellationToken) - .ConfigureAwait(false); + results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken) + .ConfigureAwait(false); } else { @@ -221,6 +227,31 @@ namespace MediaBrowser.Server.Implementations.Channels return sources; } + private readonly ConcurrentDictionary<string, Tuple<DateTime, List<ChannelMediaInfo>>> _channelItemMediaInfo = + new ConcurrentDictionary<string, Tuple<DateTime, List<ChannelMediaInfo>>>(); + + private async Task<IEnumerable<ChannelMediaInfo>> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken) + { + Tuple<DateTime, List<ChannelMediaInfo>> cachedInfo; + + if (_channelItemMediaInfo.TryGetValue(id, out cachedInfo)) + { + if ((DateTime.UtcNow - cachedInfo.Item1).TotalMinutes < 5) + { + return cachedInfo.Item2; + } + } + + var mediaInfo = await channel.GetChannelItemMediaInfo(id, cancellationToken) + .ConfigureAwait(false); + var list = mediaInfo.ToList(); + + var item2 = new Tuple<DateTime, List<ChannelMediaInfo>>(DateTime.UtcNow, list); + _channelItemMediaInfo.AddOrUpdate(id, item2, (key, oldValue) => item2); + + return list; + } + public IEnumerable<MediaSourceInfo> GetCachedChannelItemMediaSources(string id) { var item = (IChannelMediaItem)_libraryManager.GetItemById(id); @@ -515,11 +546,7 @@ namespace MediaBrowser.Server.Implementations.Channels { try { - var result = await indexable.GetLatestMedia(new ChannelLatestMediaSearch - { - UserId = userId - - }, cancellationToken).ConfigureAwait(false); + var result = await GetLatestItems(indexable, i, userId, cancellationToken).ConfigureAwait(false); var resultItems = result.ToList(); @@ -585,6 +612,65 @@ namespace MediaBrowser.Server.Implementations.Channels }; } + private async Task<IEnumerable<ChannelItemInfo>> GetLatestItems(ISupportsLatestMedia indexable, IChannel channel, string userId, CancellationToken cancellationToken) + { + var cacheLength = TimeSpan.FromHours(12); + var cachePath = GetChannelDataCachePath(channel, userId, "channelmanager-latest", null, false); + + try + { + if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow) + { + return _jsonSerializer.DeserializeFromFile<List<ChannelItemInfo>>(cachePath); + } + } + catch (FileNotFoundException) + { + + } + catch (DirectoryNotFoundException) + { + + } + + await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + try + { + if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow) + { + return _jsonSerializer.DeserializeFromFile<List<ChannelItemInfo>>(cachePath); + } + } + catch (FileNotFoundException) + { + + } + catch (DirectoryNotFoundException) + { + + } + + var result = await indexable.GetLatestMedia(new ChannelLatestMediaSearch + { + UserId = userId + + }, cancellationToken).ConfigureAwait(false); + + var resultItems = result.ToList(); + + CacheResponse(resultItems, cachePath); + + return resultItems; + } + finally + { + _resourcePool.Release(); + } + } + public async Task<QueryResult<BaseItemDto>> GetAllMedia(AllChannelMediaQuery query, CancellationToken cancellationToken) { var user = string.IsNullOrWhiteSpace(query.UserId) @@ -614,11 +700,7 @@ namespace MediaBrowser.Server.Implementations.Channels { try { - var result = await indexable.GetAllMedia(new InternalAllChannelMediaQuery - { - UserId = userId - - }, cancellationToken).ConfigureAwait(false); + var result = await GetAllItems(indexable, i, userId, cancellationToken).ConfigureAwait(false); return new Tuple<IChannel, ChannelItemResult>(i, result); } @@ -677,6 +759,63 @@ namespace MediaBrowser.Server.Implementations.Channels }; } + private async Task<ChannelItemResult> GetAllItems(IIndexableChannel indexable, IChannel channel, string userId, CancellationToken cancellationToken) + { + var cacheLength = TimeSpan.FromHours(12); + var cachePath = GetChannelDataCachePath(channel, userId, "channelmanager-allitems", null, false); + + try + { + if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow) + { + return _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath); + } + } + catch (FileNotFoundException) + { + + } + catch (DirectoryNotFoundException) + { + + } + + await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + + try + { + try + { + if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow) + { + return _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath); + } + } + catch (FileNotFoundException) + { + + } + catch (DirectoryNotFoundException) + { + + } + + var result = await indexable.GetAllMedia(new InternalAllChannelMediaQuery + { + UserId = userId + + }, cancellationToken).ConfigureAwait(false); + + CacheResponse(result, cachePath); + + return result; + } + finally + { + _resourcePool.Release(); + } + } + public async Task<QueryResult<BaseItemDto>> GetChannelItems(ChannelItemQuery query, CancellationToken cancellationToken) { var queryChannelId = query.ChannelId; @@ -764,11 +903,9 @@ namespace MediaBrowser.Server.Implementations.Channels { if (!startIndex.HasValue && !limit.HasValue) { - var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath); - if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow) { - return channelItemResult; + return _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath); } } } @@ -789,11 +926,9 @@ namespace MediaBrowser.Server.Implementations.Channels { if (!startIndex.HasValue && !limit.HasValue) { - var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath); - if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(cacheLength) > DateTime.UtcNow) { - return channelItemResult; + return _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath); } } } @@ -837,7 +972,7 @@ namespace MediaBrowser.Server.Implementations.Channels } } - private void CacheResponse(ChannelItemResult result, string path) + private void CacheResponse(object result, string path) { try { @@ -993,8 +1128,8 @@ namespace MediaBrowser.Server.Implementations.Channels item.ProductionYear = info.ProductionYear; item.ProviderIds = info.ProviderIds; - item.DateCreated = info.DateCreated.HasValue ? - info.DateCreated.Value : + item.DateCreated = info.DateCreated.HasValue ? + info.DateCreated.Value : DateTime.UtcNow; } @@ -1042,14 +1177,14 @@ namespace MediaBrowser.Server.Implementations.Channels private async Task RefreshIfNeeded(BaseItem program, CancellationToken cancellationToken) { - //if (_refreshedPrograms.ContainsKey(program.Id)) + if (_refreshedItems.ContainsKey(program.Id)) { - //return; + return; } await program.RefreshMetadata(cancellationToken).ConfigureAwait(false); - //_refreshedPrograms.TryAdd(program.Id, true); + _refreshedItems.TryAdd(program.Id, true); } internal IChannel GetChannelProvider(Channel channel) @@ -1155,5 +1290,14 @@ namespace MediaBrowser.Server.Implementations.Channels var name = _localization.GetLocalizedString("ViewTypeChannels"); return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false); } + + public void Dispose() + { + if (_refreshTimer != null) + { + _refreshTimer.Dispose(); + _refreshTimer = null; + } + } } } |
