diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 106 |
1 files changed, 59 insertions, 47 deletions
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index d704277c1..5791da1ea 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -54,11 +54,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv new ConcurrentDictionary<string, LiveStreamData>(); private List<Guid> _channelIdList = new List<Guid>(); - private Dictionary<Guid, LiveTvProgram> _programs = new Dictionary<Guid, LiveTvProgram>(); + private Dictionary<Guid, LiveTvProgram> _programs; private readonly ConcurrentDictionary<Guid, bool> _refreshedPrograms = new ConcurrentDictionary<Guid, bool>(); - private readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1); - public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager) { _config = config; @@ -109,6 +107,37 @@ namespace MediaBrowser.Server.Implementations.LiveTv _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>(); } + private readonly object _programsDataLock = new object(); + private Dictionary<Guid, LiveTvProgram> GetProgramsDictionary() + { + if (_programs == null) + { + lock (_programsDataLock) + { + if (_programs == null) + { + var dict = new Dictionary<Guid, LiveTvProgram>(); + + foreach (var item in _itemRepo.GetItemsOfType(typeof (LiveTvProgram)) + .Cast<LiveTvProgram>() + .ToList()) + { + dict[item.Id] = item; + } + + _programs = dict; + } + } + } + + return _programs; + } + + private IEnumerable<LiveTvProgram> GetPrograms() + { + return GetProgramsDictionary().Values; + } + public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken) { var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -260,7 +289,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv LiveTvProgram obj = null; - _programs.TryGetValue(guid, out obj); + GetProgramsDictionary().TryGetValue(guid, out obj); if (obj != null) { @@ -597,7 +626,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv item.ProductionYear = info.ProductionYear; item.PremiereDate = item.PremiereDate ?? info.OriginalAirDate; - + await item.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false); return item; @@ -691,7 +720,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken) { - IEnumerable<LiveTvProgram> programs = _programs.Values; + IEnumerable<LiveTvProgram> programs = GetPrograms(); if (query.MinEndDate.HasValue) { @@ -806,7 +835,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken) { - IEnumerable<LiveTvProgram> programs = _programs.Values; + IEnumerable<LiveTvProgram> programs = GetPrograms(); var user = _userManager.GetUserById(query.UserId); @@ -995,24 +1024,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken) { - await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(p * .9)); - await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false); + var innerProgress = new ActionableProgress<double>(); + innerProgress.RegisterAction(p => progress.Report(p * .9)); + await RefreshChannelsInternal(innerProgress, cancellationToken).ConfigureAwait(false); - innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); - await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); + innerProgress = new ActionableProgress<double>(); + innerProgress.RegisterAction(p => progress.Report(90 + (p * .1))); + await CleanDatabaseInternal(progress, cancellationToken).ConfigureAwait(false); - RefreshIfNeeded(_programs.Values.Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList()); - } - finally - { - _refreshSemaphore.Release(); - } + RefreshIfNeeded(GetPrograms().Where(i => (i.StartDate - DateTime.UtcNow).TotalDays <= 1).ToList()); } private async Task RefreshChannelsInternal(IProgress<double> progress, CancellationToken cancellationToken) @@ -1136,7 +1156,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(80 * percent + 10); } - _programs = programs.ToDictionary(i => i.Id); + lock (_programsDataLock) + { + _programs = programs.ToDictionary(i => i.Id); + } + _refreshedPrograms.Clear(); progress.Report(90); @@ -1147,28 +1171,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv progress.Report(100); } - public async Task CleanDatabase(IProgress<double> progress, CancellationToken cancellationToken) - { - await _refreshSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken).ConfigureAwait(false); - } - finally - { - _refreshSemaphore.Release(); - } - } - private Task CleanDatabaseInternal(IProgress<double> progress, CancellationToken cancellationToken) { - return DeleteOldPrograms(_programs.Keys.ToList(), progress, cancellationToken); + return DeleteOldPrograms(GetProgramsDictionary().Keys.ToList(), progress, cancellationToken); } private async Task DeleteOldPrograms(List<Guid> currentIdList, IProgress<double> progress, CancellationToken cancellationToken) { - var list = _itemRepo.GetItemsOfType(typeof(LiveTvProgram)).ToList(); + var list = _itemRepo.GetItemIdsOfType(typeof(LiveTvProgram)).ToList(); var numComplete = 0; @@ -1549,7 +1559,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var now = DateTime.UtcNow; - var program = _programs.Values + var program = GetPrograms() .Where(i => string.Equals(externalChannelId, i.ExternalChannelId, StringComparison.OrdinalIgnoreCase)) .OrderBy(i => i.StartDate) .SkipWhile(i => now >= (i.EndDate ?? DateTime.MinValue)) @@ -1742,7 +1752,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var dtoOptions = new DtoOptions(); dtoOptions.Fields.Remove(ItemFields.SyncInfo); - + var recordingResult = await GetRecordings(new RecordingQuery { UserId = query.UserId @@ -1855,13 +1865,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv public GuideInfo GetGuideInfo() { - var programs = _programs.ToList(); + var programs = GetPrograms().OrderBy(i => i.StartDate).ToList(); - var startDate = _programs.Count == 0 ? DateTime.MinValue : - programs.Select(i => i.Value.StartDate).Min(); + var startDate = programs.Count == 0 ? + DateTime.MinValue : + programs[0].StartDate; - var endDate = programs.Count == 0 ? DateTime.MinValue : - programs.Select(i => i.Value.StartDate).Max(); + var endDate = programs.Count == 0 ? + DateTime.MinValue : + programs[programs.Count - 1].StartDate; return new GuideInfo { |
