diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-06-20 00:50:30 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-06-20 00:50:30 -0400 |
| commit | 439839378364466ae7795c99b67a123bd1008945 (patch) | |
| tree | 0923656b58425f72df354eb71fd69109eddbe8c8 /MediaBrowser.Server.Implementations | |
| parent | e666fee20dd4a8343a262b9225023996b54b1004 (diff) | |
close ffmpeg more gracefully
Diffstat (limited to 'MediaBrowser.Server.Implementations')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Channels/ChannelManager.cs | 196 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 4 |
2 files changed, 172 insertions, 28 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; + } + } } } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index c6a632fec..521a6f843 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1497,7 +1497,7 @@ namespace MediaBrowser.Server.Implementations.Library public async Task<UserView> GetNamedView(string name, string type, string sortName, CancellationToken cancellationToken) { - var id = "namedview_2_" + name; + var id = "namedview_3_" + name; var guid = id.GetMD5(); var item = GetItemById(guid) as UserView; @@ -1506,7 +1506,7 @@ namespace MediaBrowser.Server.Implementations.Library { var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath, "views", - _fileSystem.GetValidFilename(name)); + _fileSystem.GetValidFilename(type)); Directory.CreateDirectory(Path.GetDirectoryName(path)); |
