aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Channels/ChannelManager.cs')
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs196
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;
+ }
+ }
}
}