From 6ac9da8bed32e551d23cf6287c413927ef7c1e8d Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 8 Jan 2018 20:02:56 +0000 Subject: [PATCH] Some memory management improvements --- src/Ombi.Api.Plex/PlexApi.cs | 3 +- src/Ombi.Api/Api.cs | 120 +++++++----------- src/Ombi.DependencyInjection/IocExtensions.cs | 3 +- src/Ombi.Schedule/IoCJobActivator.cs | 10 +- .../Jobs/Emby/EmbyAvaliabilityChecker.cs | 19 +++ .../Jobs/Emby/EmbyContentSync.cs | 20 +++ .../Jobs/Emby/EmbyEpisodeSync.cs | 21 +++ .../Jobs/Emby/EmbyUserImporter.cs | 22 ++++ .../Jobs/Emby/IEmbyAvaliabilityChecker.cs | 2 +- .../Jobs/Emby/IEmbyContentSync.cs | 2 +- .../Jobs/Emby/IEmbyEpisodeSync.cs | 2 +- .../Jobs/Emby/IEmbyUserImporter.cs | 2 +- src/Ombi.Schedule/Jobs/IBaseJob.cs | 36 ++++++ .../Interfaces/IPlexAvailabilityChecker.cs | 2 +- .../Jobs/Plex/Interfaces/IPlexContentSync.cs | 2 +- .../Jobs/Plex/Interfaces/IPlexEpisodeSync.cs | 7 +- .../Jobs/Plex/Interfaces/IPlexUserImporter.cs | 2 +- .../Jobs/Plex/PlexAvailabilityChecker.cs | 20 +++ .../Jobs/Plex/PlexContentSync.cs | 22 ++++ .../Jobs/Plex/PlexEpisodeSync.cs | 24 +++- .../Jobs/Plex/PlexUserImporter.cs | 21 +++ .../Settings/ISettingsService.cs | 5 +- src/Ombi.Settings/Settings/SettingsService.cs | 19 +++ src/Ombi.Store/Context/OmbiContext.cs | 1 - .../Repository/EmbyContentRepository.cs | 20 +++ .../Repository/IEmbyContentRepository.cs | 5 +- src/Ombi.Store/Repository/IRepository.cs | 2 +- .../Repository/ISettingsRepository.cs | 5 +- src/Ombi.Store/Repository/Repository.cs | 22 ++++ .../Repository/SettingsJsonRepository.cs | 19 +++ 30 files changed, 361 insertions(+), 99 deletions(-) create mode 100644 src/Ombi.Schedule/Jobs/IBaseJob.cs diff --git a/src/Ombi.Api.Plex/PlexApi.cs b/src/Ombi.Api.Plex/PlexApi.cs index f06a7e465..b5c6b958d 100644 --- a/src/Ombi.Api.Plex/PlexApi.cs +++ b/src/Ombi.Api.Plex/PlexApi.cs @@ -26,8 +26,7 @@ namespace Ombi.Api.Plex /// This is for authenticating users credentials with Plex /// NOTE: Plex "Managed" users do not work /// - /// - /// + /// /// public async Task SignIn(UserRequest user) { diff --git a/src/Ombi.Api/Api.cs b/src/Ombi.Api/Api.cs index 5f9acb8a4..c12258b8e 100644 --- a/src/Ombi.Api/Api.cs +++ b/src/Ombi.Api/Api.cs @@ -1,32 +1,23 @@ -using System; -using System.IO; +using System.IO; using System.Net.Http; using System.Net.Http.Headers; -using System.Security.Authentication; using System.Threading.Tasks; using System.Xml.Serialization; -using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using Microsoft.Extensions.Logging; -using Ombi.Core.Settings; using Ombi.Helpers; -using Ombi.Settings.Settings.Models; namespace Ombi.Api { public class Api : IApi { - public Api(ILogger log, ISettingsService s, ICacheService cache, IOmbiHttpClient client) + public Api(ILogger log, IOmbiHttpClient client) { Logger = log; - _settings = s; - _cache = cache; _client = client; } private ILogger Logger { get; } - private readonly ISettingsService _settings; - private readonly ICacheService _cache; private readonly IOmbiHttpClient _client; private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings @@ -38,41 +29,29 @@ namespace Ombi.Api { using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri)) { - // Add the Json Body - if (request.JsonBody != null) + AddHeadersBody(request, httpRequestMessage); + + var httpResponseMessage = await _client.SendAsync(httpRequestMessage); + + if (!httpResponseMessage.IsSuccessStatusCode) { - httpRequestMessage.Content = new JsonContent(request.JsonBody); - httpRequestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // Emby connect fails if we have the charset in the header + LogError(request, httpResponseMessage); } - // Add headers - foreach (var header in request.Headers) + // do something with the response + var receivedString = await httpResponseMessage.Content.ReadAsStringAsync(); + if (request.ContentType == ContentType.Json) { - httpRequestMessage.Headers.Add(header.Key, header.Value); - + request.OnBeforeDeserialization?.Invoke(receivedString); + return JsonConvert.DeserializeObject(receivedString, Settings); } - using (var httpResponseMessage = await _client.SendAsync(httpRequestMessage)) + else { - if (!httpResponseMessage.IsSuccessStatusCode) - { - LogError(request, httpResponseMessage); - } - // do something with the response - var data = httpResponseMessage.Content; - var receivedString = await data.ReadAsStringAsync(); - if (request.ContentType == ContentType.Json) - { - request.OnBeforeDeserialization?.Invoke(receivedString); - return JsonConvert.DeserializeObject(receivedString, Settings); - } - else - { - // XML - XmlSerializer serializer = new XmlSerializer(typeof(T)); - StringReader reader = new StringReader(receivedString); - var value = (T)serializer.Deserialize(reader); - return value; - } + // XML + XmlSerializer serializer = new XmlSerializer(typeof(T)); + StringReader reader = new StringReader(receivedString); + var value = (T)serializer.Deserialize(reader); + return value; } } @@ -82,30 +61,17 @@ namespace Ombi.Api { using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri)) { - // Add the Json Body - if (request.JsonBody != null) - { - httpRequestMessage.Content = new JsonContent(request.JsonBody); - } + AddHeadersBody(request, httpRequestMessage); - // Add headers - foreach (var header in request.Headers) + var httpResponseMessage = await _client.SendAsync(httpRequestMessage); + if (!httpResponseMessage.IsSuccessStatusCode) { - httpRequestMessage.Headers.Add(header.Key, header.Value); - + LogError(request, httpResponseMessage); } - using (var httpResponseMessage = await _client.SendAsync(httpRequestMessage)) - { - if (!httpResponseMessage.IsSuccessStatusCode) - { - LogError(request, httpResponseMessage); - } - // do something with the response - var data = httpResponseMessage.Content; - + // do something with the response + var data = httpResponseMessage.Content; - return await data.ReadAsStringAsync(); - } + return await data.ReadAsStringAsync(); } } @@ -114,25 +80,29 @@ namespace Ombi.Api { using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri)) { - // Add the Json Body - if (request.JsonBody != null) + AddHeadersBody(request, httpRequestMessage); + var httpResponseMessage = await _client.SendAsync(httpRequestMessage); + if (!httpResponseMessage.IsSuccessStatusCode) { - httpRequestMessage.Content = new JsonContent(request.JsonBody); + LogError(request, httpResponseMessage); } + } + } - // Add headers - foreach (var header in request.Headers) - { - httpRequestMessage.Headers.Add(header.Key, header.Value); + private static void AddHeadersBody(Request request, HttpRequestMessage httpRequestMessage) + { + // Add the Json Body + if (request.JsonBody != null) + { + httpRequestMessage.Content = new JsonContent(request.JsonBody); + httpRequestMessage.Content.Headers.ContentType = + new MediaTypeHeaderValue("application/json"); // Emby connect fails if we have the charset in the header + } - } - using (var httpResponseMessage = await _client.SendAsync(httpRequestMessage)) - { - if (!httpResponseMessage.IsSuccessStatusCode) - { - LogError(request, httpResponseMessage); - } - } + // Add headers + foreach (var header in request.Headers) + { + httpRequestMessage.Headers.Add(header.Key, header.Value); } } diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 77350db40..770109854 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -50,6 +50,7 @@ using Ombi.Store.Repository.Requests; using Ombi.Updater; using PlexContentCacher = Ombi.Schedule.Jobs.Plex; using Ombi.Api.Telegram; +using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Schedule.Jobs.SickRage; namespace Ombi.DependencyInjection @@ -85,7 +86,7 @@ namespace Ombi.DependencyInjection public static void RegisterApi(this IServiceCollection services) { - services.AddTransient(); + services.AddSingleton(); services.AddSingleton(); // https://blogs.msdn.microsoft.com/alazarev/2017/12/29/disposable-finalizers-and-httpclient/ services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.Schedule/IoCJobActivator.cs b/src/Ombi.Schedule/IoCJobActivator.cs index 81c7c8d6e..787ef8b6d 100644 --- a/src/Ombi.Schedule/IoCJobActivator.cs +++ b/src/Ombi.Schedule/IoCJobActivator.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Reflection; using Hangfire; +using Microsoft.Extensions.DependencyInjection; namespace Ombi.Schedule { @@ -15,8 +16,13 @@ namespace Ombi.Schedule public override object ActivateJob(Type type) { - var i = type.GetTypeInfo().ImplementedInterfaces.FirstOrDefault(); - return _container.GetService(i); + var scopeFactory = _container.GetService(); + var scope = scopeFactory.CreateScope(); + var scopedContainer = scope.ServiceProvider; + + var interfaceType = type.GetTypeInfo().ImplementedInterfaces.FirstOrDefault(); + var implementation = scopedContainer.GetRequiredService(interfaceType); + return implementation; } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs index ab4954628..af5f58cb4 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs @@ -148,5 +148,24 @@ namespace Ombi.Schedule.Jobs.Emby await _tvRepo.Save(); } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _movieRepo?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index ed5844e5c..9d054ea7c 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -139,6 +139,26 @@ namespace Ombi.Schedule.Jobs.Emby return true; } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _settings?.Dispose(); + _repo?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index c7f190558..0e1a3dc79 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -121,5 +121,26 @@ namespace Ombi.Schedule.Jobs.Emby await _repo.AddRange(epToAdd); } } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _settings?.Dispose(); + _repo?.Dispose(); + _avaliabilityChecker?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs index 6068e037a..a28a56ba2 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs @@ -25,6 +25,7 @@ // ************************************************************************/ #endregion +using System; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; @@ -142,5 +143,26 @@ namespace Ombi.Schedule.Jobs.Emby } } } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _userManager?.Dispose(); + _embySettings?.Dispose(); + _userManagementSettings?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs index db9c58079..ce9792f3b 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs @@ -2,7 +2,7 @@ namespace Ombi.Schedule.Jobs.Emby { - public interface IEmbyAvaliabilityChecker + public interface IEmbyAvaliabilityChecker : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs index dc6e7514e..5ba8ea6f9 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; namespace Ombi.Schedule.Jobs.Emby { - public interface IEmbyContentSync + public interface IEmbyContentSync : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs index 965a6fb73..42d761832 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs @@ -2,7 +2,7 @@ namespace Ombi.Schedule.Jobs.Emby { - public interface IEmbyEpisodeSync + public interface IEmbyEpisodeSync : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs index 595505f61..c8bd6fc0e 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs @@ -2,7 +2,7 @@ namespace Ombi.Schedule.Jobs.Emby { - public interface IEmbyUserImporter + public interface IEmbyUserImporter : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/IBaseJob.cs b/src/Ombi.Schedule/Jobs/IBaseJob.cs new file mode 100644 index 000000000..d43d21b9a --- /dev/null +++ b/src/Ombi.Schedule/Jobs/IBaseJob.cs @@ -0,0 +1,36 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2018 Jamie Rees +// File: IBaseJob.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; + +namespace Ombi.Schedule +{ + public interface IBaseJob : IDisposable + { + + } +} \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs index 0f65ddeb8..3de9749d6 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs @@ -2,7 +2,7 @@ namespace Ombi.Schedule.Jobs.Plex { - public interface IPlexAvailabilityChecker + public interface IPlexAvailabilityChecker : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs index 8f1ddb5fd..a9fadae9d 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs @@ -2,7 +2,7 @@ namespace Ombi.Schedule.Jobs { - public interface IPlexContentSync + public interface IPlexContentSync : IBaseJob { Task CacheContent(); } diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs index a150fa773..7d97381be 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs @@ -1,8 +1,9 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; -namespace Ombi.Schedule.Jobs.Plex +namespace Ombi.Schedule.Jobs.Plex.Interfaces { - public interface IPlexEpisodeSync + public interface IPlexEpisodeSync : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs index b3ec7ad10..431ce3ee3 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs @@ -2,7 +2,7 @@ namespace Ombi.Schedule.Jobs.Plex { - public interface IPlexUserImporter + public interface IPlexUserImporter : IBaseJob { Task Start(); } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs index adb9b7d30..7a58345f1 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs @@ -143,5 +143,25 @@ namespace Ombi.Schedule.Jobs.Plex await _movieRepo.Save(); } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _movieRepo?.Dispose(); + _repo?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index c644aba54..5472d671d 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -36,6 +36,7 @@ using Ombi.Api.Plex.Models; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; +using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Store.Entities; using Ombi.Store.Repository; @@ -303,5 +304,26 @@ namespace Ombi.Schedule.Jobs.Plex } return plex.Enable; } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + Plex?.Dispose(); + Repo?.Dispose(); + EpisodeSync?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index a05ba6a0a..c6630ee0e 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -3,12 +3,14 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Hangfire; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Api.Plex; using Ombi.Api.Plex.Models; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; +using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Store.Entities; using Ombi.Store.Repository; @@ -99,7 +101,7 @@ namespace Ombi.Schedule.Jobs.Plex var currentPosition = 0; var resultCount = settings.EpisodeBatchSize == 0 ? 50 : settings.EpisodeBatchSize; var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount); - var currentData = _repo.GetAllEpisodes(); + var currentData = _repo.GetAllEpisodes().AsNoTracking(); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}"); await ProcessEpsiodes(episodes, currentData); @@ -159,5 +161,25 @@ namespace Ombi.Schedule.Jobs.Plex return true; } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _repo?.Dispose(); + _settings?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs index 73dee859f..22211ea6d 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs @@ -169,5 +169,26 @@ namespace Ombi.Schedule.Jobs.Plex } return result.Succeeded; } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _userManager?.Dispose(); + _plexSettings?.Dispose(); + _userManagementSettings?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/ISettingsService.cs b/src/Ombi.Settings/Settings/ISettingsService.cs index e8f40733c..70c5ebeb8 100644 --- a/src/Ombi.Settings/Settings/ISettingsService.cs +++ b/src/Ombi.Settings/Settings/ISettingsService.cs @@ -1,8 +1,9 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; namespace Ombi.Core.Settings { - public interface ISettingsService + public interface ISettingsService : IDisposable { T GetSettings(); Task GetSettingsAsync(); diff --git a/src/Ombi.Settings/Settings/SettingsService.cs b/src/Ombi.Settings/Settings/SettingsService.cs index e5c5409a2..3162c34c2 100644 --- a/src/Ombi.Settings/Settings/SettingsService.cs +++ b/src/Ombi.Settings/Settings/SettingsService.cs @@ -155,5 +155,24 @@ namespace Ombi.Settings.Settings return settings.Content; //return _protector.Unprotect(settings.Content); } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + Repo?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index edf21009e..37149a9e5 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -18,7 +18,6 @@ namespace Ombi.Store.Context _created = true; Database.Migrate(); - } public DbSet NotificationTemplates { get; set; } diff --git a/src/Ombi.Store/Repository/EmbyContentRepository.cs b/src/Ombi.Store/Repository/EmbyContentRepository.cs index 314fa0042..519138edc 100644 --- a/src/Ombi.Store/Repository/EmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/EmbyContentRepository.cs @@ -25,6 +25,7 @@ // ************************************************************************/ #endregion +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -109,5 +110,24 @@ namespace Ombi.Store.Repository Db.EmbyEpisode.AddRange(content); await Db.SaveChangesAsync(); } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + Db?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IEmbyContentRepository.cs b/src/Ombi.Store/Repository/IEmbyContentRepository.cs index bc10a6273..e6fe18067 100644 --- a/src/Ombi.Store/Repository/IEmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/IEmbyContentRepository.cs @@ -1,11 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IEmbyContentRepository + public interface IEmbyContentRepository : IDisposable { Task Add(EmbyContent content); Task AddRange(IEnumerable content); diff --git a/src/Ombi.Store/Repository/IRepository.cs b/src/Ombi.Store/Repository/IRepository.cs index 6e7c394e3..9df78f083 100644 --- a/src/Ombi.Store/Repository/IRepository.cs +++ b/src/Ombi.Store/Repository/IRepository.cs @@ -8,7 +8,7 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IRepository where T : Entity + public interface IRepository : IDisposable where T : Entity { Task Find(object key); IQueryable GetAll(); diff --git a/src/Ombi.Store/Repository/ISettingsRepository.cs b/src/Ombi.Store/Repository/ISettingsRepository.cs index 3b24ded5e..1c2729245 100644 --- a/src/Ombi.Store/Repository/ISettingsRepository.cs +++ b/src/Ombi.Store/Repository/ISettingsRepository.cs @@ -1,10 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface ISettingsRepository + public interface ISettingsRepository : IDisposable { /// /// Inserts the specified entity. diff --git a/src/Ombi.Store/Repository/Repository.cs b/src/Ombi.Store/Repository/Repository.cs index 90861e36b..f7c12709f 100644 --- a/src/Ombi.Store/Repository/Repository.cs +++ b/src/Ombi.Store/Repository/Repository.cs @@ -71,5 +71,27 @@ namespace Ombi.Store.Repository { return source.Include(navigationPropertyPath); } + + + private bool _disposed; + // Protected implementation of Dispose pattern. + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + _ctx?.Dispose(); + } + + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/SettingsJsonRepository.cs b/src/Ombi.Store/Repository/SettingsJsonRepository.cs index ba195c372..09bf61695 100644 --- a/src/Ombi.Store/Repository/SettingsJsonRepository.cs +++ b/src/Ombi.Store/Repository/SettingsJsonRepository.cs @@ -89,5 +89,24 @@ namespace Ombi.Store.Repository { return $"{entity}Json"; } + + private bool _disposed; + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + Db?.Dispose(); + } + _disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } } \ No newline at end of file