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.cs90
1 files changed, 82 insertions, 8 deletions
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
index dc3a04769..662bbdf3e 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
+using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
@@ -33,8 +34,9 @@ namespace MediaBrowser.Server.Implementations.Channels
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
+ private readonly IJsonSerializer _jsonSerializer;
- public ChannelManager(IUserManager userManager, IDtoService dtoService, ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IUserDataManager userDataManager)
+ public ChannelManager(IUserManager userManager, IDtoService dtoService, ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IUserDataManager userDataManager, IJsonSerializer jsonSerializer)
{
_userManager = userManager;
_dtoService = dtoService;
@@ -43,6 +45,7 @@ namespace MediaBrowser.Server.Implementations.Channels
_config = config;
_fileSystem = fileSystem;
_userDataManager = userDataManager;
+ _jsonSerializer = jsonSerializer;
}
public void AddParts(IEnumerable<IChannel> channels, IEnumerable<IChannelFactory> factories)
@@ -227,19 +230,90 @@ namespace MediaBrowser.Server.Implementations.Channels
return await GetReturnItems(items, user, query, cancellationToken).ConfigureAwait(false);
}
+ private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
private async Task<IEnumerable<ChannelItemInfo>> GetChannelItems(IChannel channel, User user, string categoryId, CancellationToken cancellationToken)
{
- // TODO: Put some caching in here
+ var cachePath = GetChannelDataCachePath(channel, user, categoryId);
- var query = new InternalChannelItemQuery
+ try
{
- User = user,
- CategoryId = categoryId
- };
+ var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
+
+ if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(channelItemResult.CacheLength) > DateTime.UtcNow)
+ {
+ return channelItemResult.Items;
+ }
+ }
+ catch (FileNotFoundException)
+ {
+
+ }
+ catch (DirectoryNotFoundException)
+ {
+
+ }
+
+ await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ try
+ {
+ var channelItemResult = _jsonSerializer.DeserializeFromFile<ChannelItemResult>(cachePath);
+
+ if (_fileSystem.GetLastWriteTimeUtc(cachePath).Add(channelItemResult.CacheLength) > DateTime.UtcNow)
+ {
+ return channelItemResult.Items;
+ }
+ }
+ catch (FileNotFoundException)
+ {
+
+ }
+ catch (DirectoryNotFoundException)
+ {
+
+ }
+
+ var query = new InternalChannelItemQuery
+ {
+ User = user,
+ CategoryId = categoryId
+ };
+
+ var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);
+
+ CacheResponse(result, cachePath);
+
+ return result.Items;
+ }
+ finally
+ {
+ _resourcePool.Release();
+ }
+ }
+
+ private void CacheResponse(ChannelItemResult result, string path)
+ {
+ try
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+
+ _jsonSerializer.SerializeToFile(result, path);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error writing to channel cache file: {0}", ex, path);
+ }
+ }
+
+ private string GetChannelDataCachePath(IChannel channel, User user, string categoryId)
+ {
+ var channelId = GetInternalChannelId(channel.Name).ToString("N");
- var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false);
+ var categoryKey = string.IsNullOrWhiteSpace(categoryId) ? "root" : categoryId.GetMD5().ToString("N");
- return result.Items;
+ return Path.Combine(_config.ApplicationPaths.CachePath, channelId, categoryKey, user.Id.ToString("N") + ".json");
}
private async Task<QueryResult<BaseItemDto>> GetReturnItems(IEnumerable<ChannelItemInfo> items, User user, ChannelItemQuery query, CancellationToken cancellationToken)