Fix interceptor memory leaks (#66)
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using Castle.DynamicProxy;
|
|
||||||
using Common.Configuration.General;
|
using Common.Configuration.General;
|
||||||
using Common.Helpers;
|
using Common.Helpers;
|
||||||
using Infrastructure.Interceptors;
|
|
||||||
using Infrastructure.Verticals.DownloadClient.Deluge;
|
using Infrastructure.Verticals.DownloadClient.Deluge;
|
||||||
using Infrastructure.Verticals.Notifications.Consumers;
|
using Infrastructure.Verticals.Notifications.Consumers;
|
||||||
using Infrastructure.Verticals.Notifications.Models;
|
using Infrastructure.Verticals.Notifications.Models;
|
||||||
@@ -42,8 +40,7 @@ public static class MainDI
|
|||||||
e.PrefetchCount = 1;
|
e.PrefetchCount = 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
.AddDryRunInterceptor();
|
|
||||||
|
|
||||||
private static IServiceCollection AddHttpClients(this IServiceCollection services, IConfiguration configuration)
|
private static IServiceCollection AddHttpClients(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
@@ -91,31 +88,4 @@ public static class MainDI
|
|||||||
.OrResult(response => !response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Unauthorized)
|
.OrResult(response => !response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Unauthorized)
|
||||||
.WaitAndRetryAsync(config.MaxRetries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
|
.WaitAndRetryAsync(config.MaxRetries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
|
||||||
);
|
);
|
||||||
|
|
||||||
private static IServiceCollection AddDryRunInterceptor(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services
|
|
||||||
.Where(s => s.ServiceType != typeof(IDryRunService) && typeof(IDryRunService).IsAssignableFrom(s.ServiceType))
|
|
||||||
.ToList()
|
|
||||||
.ForEach(service =>
|
|
||||||
{
|
|
||||||
services.Decorate(service.ServiceType, (target, svc) =>
|
|
||||||
{
|
|
||||||
ProxyGenerator proxyGenerator = new();
|
|
||||||
DryRunAsyncInterceptor interceptor = svc.GetRequiredService<DryRunAsyncInterceptor>();
|
|
||||||
|
|
||||||
object implementation = proxyGenerator.CreateClassProxyWithTarget(
|
|
||||||
service.ServiceType,
|
|
||||||
target,
|
|
||||||
interceptor
|
|
||||||
);
|
|
||||||
|
|
||||||
((IInterceptedService)target).Proxy = implementation;
|
|
||||||
|
|
||||||
return implementation;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ public static class NotificationsDI
|
|||||||
.Configure<NotifiarrConfig>(configuration.GetSection(NotifiarrConfig.SectionName))
|
.Configure<NotifiarrConfig>(configuration.GetSection(NotifiarrConfig.SectionName))
|
||||||
.AddTransient<INotifiarrProxy, NotifiarrProxy>()
|
.AddTransient<INotifiarrProxy, NotifiarrProxy>()
|
||||||
.AddTransient<INotificationProvider, NotifiarrProvider>()
|
.AddTransient<INotificationProvider, NotifiarrProvider>()
|
||||||
.AddTransient<NotificationPublisher>()
|
.AddTransient<INotificationPublisher, NotificationPublisher>()
|
||||||
.AddTransient<INotificationFactory, NotificationFactory>()
|
.AddTransient<INotificationFactory, NotificationFactory>()
|
||||||
.AddTransient<NotificationService>();
|
.AddTransient<NotificationService>();
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ public static class ServicesDI
|
|||||||
{
|
{
|
||||||
public static IServiceCollection AddServices(this IServiceCollection services) =>
|
public static IServiceCollection AddServices(this IServiceCollection services) =>
|
||||||
services
|
services
|
||||||
.AddTransient<DryRunAsyncInterceptor>()
|
.AddTransient<IDryRunInterceptor, DryRunInterceptor>()
|
||||||
.AddTransient<SonarrClient>()
|
.AddTransient<SonarrClient>()
|
||||||
.AddTransient<RadarrClient>()
|
.AddTransient<RadarrClient>()
|
||||||
.AddTransient<LidarrClient>()
|
.AddTransient<LidarrClient>()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Common.Configuration.ContentBlocker;
|
using Common.Configuration.ContentBlocker;
|
||||||
using Common.Configuration.DownloadCleaner;
|
using Common.Configuration.DownloadCleaner;
|
||||||
using Common.Configuration.QueueCleaner;
|
using Common.Configuration.QueueCleaner;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.ContentBlocker;
|
using Infrastructure.Verticals.ContentBlocker;
|
||||||
using Infrastructure.Verticals.DownloadClient;
|
using Infrastructure.Verticals.DownloadClient;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
@@ -53,7 +54,8 @@ public class DownloadServiceFixture : IDisposable
|
|||||||
downloadCleanerOptions.Value.Returns(new DownloadCleanerConfig());
|
downloadCleanerOptions.Value.Returns(new DownloadCleanerConfig());
|
||||||
|
|
||||||
var filenameEvaluator = Substitute.For<IFilenameEvaluator>();
|
var filenameEvaluator = Substitute.For<IFilenameEvaluator>();
|
||||||
var notifier = Substitute.For<NotificationPublisher>();
|
var notifier = Substitute.For<INotificationPublisher>();
|
||||||
|
var dryRunInterceptor = Substitute.For<IDryRunInterceptor>();
|
||||||
|
|
||||||
return new TestDownloadService(
|
return new TestDownloadService(
|
||||||
Logger,
|
Logger,
|
||||||
@@ -63,7 +65,8 @@ public class DownloadServiceFixture : IDisposable
|
|||||||
Cache,
|
Cache,
|
||||||
filenameEvaluator,
|
filenameEvaluator,
|
||||||
Striker,
|
Striker,
|
||||||
notifier
|
notifier,
|
||||||
|
dryRunInterceptor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Text.RegularExpressions;
|
|||||||
using Common.Configuration.ContentBlocker;
|
using Common.Configuration.ContentBlocker;
|
||||||
using Common.Configuration.DownloadCleaner;
|
using Common.Configuration.DownloadCleaner;
|
||||||
using Common.Configuration.QueueCleaner;
|
using Common.Configuration.QueueCleaner;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.ContentBlocker;
|
using Infrastructure.Verticals.ContentBlocker;
|
||||||
using Infrastructure.Verticals.DownloadClient;
|
using Infrastructure.Verticals.DownloadClient;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
@@ -23,9 +24,12 @@ public class TestDownloadService : DownloadService
|
|||||||
IMemoryCache cache,
|
IMemoryCache cache,
|
||||||
IFilenameEvaluator filenameEvaluator,
|
IFilenameEvaluator filenameEvaluator,
|
||||||
IStriker striker,
|
IStriker striker,
|
||||||
NotificationPublisher notifier)
|
INotificationPublisher notifier,
|
||||||
: base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig,
|
IDryRunInterceptor dryRunInterceptor
|
||||||
cache, filenameEvaluator, striker, notifier)
|
) : base(
|
||||||
|
logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache,
|
||||||
|
filenameEvaluator, striker, notifier, dryRunInterceptor
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
|
|
||||||
<PackageReference Include="FLM.QBittorrent" Version="1.0.0" />
|
<PackageReference Include="FLM.QBittorrent" Version="1.0.0" />
|
||||||
<PackageReference Include="FLM.Transmission" Version="1.0.2" />
|
<PackageReference Include="FLM.Transmission" Version="1.0.2" />
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Castle.DynamicProxy;
|
|
||||||
using Common.Attributes;
|
using Common.Attributes;
|
||||||
using Common.Configuration.General;
|
using Common.Configuration.General;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -7,41 +6,70 @@ using Microsoft.Extensions.Options;
|
|||||||
|
|
||||||
namespace Infrastructure.Interceptors;
|
namespace Infrastructure.Interceptors;
|
||||||
|
|
||||||
public class DryRunAsyncInterceptor : AsyncInterceptorBase
|
public class DryRunInterceptor : IDryRunInterceptor
|
||||||
{
|
{
|
||||||
private readonly ILogger<DryRunAsyncInterceptor> _logger;
|
private readonly ILogger<DryRunInterceptor> _logger;
|
||||||
private readonly DryRunConfig _config;
|
private readonly DryRunConfig _config;
|
||||||
|
|
||||||
public DryRunAsyncInterceptor(ILogger<DryRunAsyncInterceptor> logger, IOptions<DryRunConfig> config)
|
public DryRunInterceptor(ILogger<DryRunInterceptor> logger, IOptions<DryRunConfig> config)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_config = config.Value;
|
_config = config.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task> proceed)
|
public void Intercept(Action action)
|
||||||
{
|
{
|
||||||
MethodInfo? method = invocation.MethodInvocationTarget ?? invocation.Method;
|
MethodInfo methodInfo = action.Method;
|
||||||
if (IsDryRun(method))
|
|
||||||
|
if (IsDryRun(methodInfo))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("[DRY RUN] skipping method: {name}", method.Name);
|
_logger.LogInformation("[DRY RUN] skipping method: {name}", methodInfo.Name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await proceed(invocation, proceedInfo);
|
action();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task<TResult> InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
|
public Task InterceptAsync(Delegate action, params object[] parameters)
|
||||||
{
|
{
|
||||||
MethodInfo? method = invocation.MethodInvocationTarget ?? invocation.Method;
|
MethodInfo methodInfo = action.Method;
|
||||||
if (IsDryRun(method))
|
|
||||||
|
if (IsDryRun(methodInfo))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("[DRY RUN] skipping method: {name}", method.Name);
|
_logger.LogInformation("[DRY RUN] skipping method: {name}", methodInfo.Name);
|
||||||
return default!;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await proceed(invocation, proceedInfo);
|
object? result = action.DynamicInvoke(parameters);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (result is Task task)
|
||||||
|
{
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T?> InterceptAsync<T>(Delegate action, params object[] parameters)
|
||||||
|
{
|
||||||
|
MethodInfo methodInfo = action.Method;
|
||||||
|
|
||||||
|
if (IsDryRun(methodInfo))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("[DRY RUN] skipping method: {name}", methodInfo.Name);
|
||||||
|
return Task.FromResult(default(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
object? result = action.DynamicInvoke(parameters);
|
||||||
|
|
||||||
|
if (result is Task<T?> task)
|
||||||
|
{
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(default(T));
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsDryRun(MethodInfo method)
|
private bool IsDryRun(MethodInfo method)
|
||||||
{
|
{
|
||||||
return method.GetCustomAttributes(typeof(DryRunSafeguardAttribute), true).Any() && _config.IsDryRun;
|
return method.GetCustomAttributes(typeof(DryRunSafeguardAttribute), true).Any() && _config.IsDryRun;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Infrastructure.Interceptors;
|
||||||
|
|
||||||
|
public interface IDryRunInterceptor
|
||||||
|
{
|
||||||
|
void Intercept(Action action);
|
||||||
|
|
||||||
|
Task InterceptAsync(Delegate action, params object[] parameters);
|
||||||
|
|
||||||
|
Task<T?> InterceptAsync<T>(Delegate action, params object[] parameters);
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
namespace Infrastructure.Interceptors;
|
|
||||||
|
|
||||||
public interface IDryRunService : IInterceptedService
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Infrastructure.Interceptors;
|
|
||||||
|
|
||||||
public interface IInterceptedService
|
|
||||||
{
|
|
||||||
public object Proxy { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
namespace Infrastructure.Interceptors;
|
|
||||||
|
|
||||||
public class InterceptedService : IInterceptedService
|
|
||||||
{
|
|
||||||
private object? _proxy;
|
|
||||||
|
|
||||||
public object Proxy
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_proxy is null)
|
|
||||||
{
|
|
||||||
throw new Exception("Proxy is not set");
|
|
||||||
}
|
|
||||||
|
|
||||||
return _proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
set => _proxy = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,27 +15,22 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Infrastructure.Verticals.Arr;
|
namespace Infrastructure.Verticals.Arr;
|
||||||
|
|
||||||
public abstract class ArrClient : InterceptedService, IArrClient, IDryRunService
|
public abstract class ArrClient : IArrClient
|
||||||
{
|
{
|
||||||
protected readonly ILogger<ArrClient> _logger;
|
protected readonly ILogger<ArrClient> _logger;
|
||||||
protected readonly HttpClient _httpClient;
|
protected readonly HttpClient _httpClient;
|
||||||
protected readonly LoggingConfig _loggingConfig;
|
protected readonly LoggingConfig _loggingConfig;
|
||||||
protected readonly QueueCleanerConfig _queueCleanerConfig;
|
protected readonly QueueCleanerConfig _queueCleanerConfig;
|
||||||
protected readonly IStriker _striker;
|
protected readonly IStriker _striker;
|
||||||
|
protected readonly IDryRunInterceptor _dryRunInterceptor;
|
||||||
/// <summary>
|
|
||||||
/// Constructor to be used by interceptors.
|
|
||||||
/// </summary>
|
|
||||||
protected ArrClient()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ArrClient(
|
protected ArrClient(
|
||||||
ILogger<ArrClient> logger,
|
ILogger<ArrClient> logger,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IOptions<LoggingConfig> loggingConfig,
|
IOptions<LoggingConfig> loggingConfig,
|
||||||
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
||||||
IStriker striker
|
IStriker striker,
|
||||||
|
IDryRunInterceptor dryRunInterceptor
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -43,6 +38,7 @@ public abstract class ArrClient : InterceptedService, IArrClient, IDryRunService
|
|||||||
_loggingConfig = loggingConfig.Value;
|
_loggingConfig = loggingConfig.Value;
|
||||||
_queueCleanerConfig = queueCleanerConfig.Value;
|
_queueCleanerConfig = queueCleanerConfig.Value;
|
||||||
_striker = striker;
|
_striker = striker;
|
||||||
|
_dryRunInterceptor = dryRunInterceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<QueueListResponse> GetQueueItemsAsync(ArrInstance arrInstance, int page)
|
public virtual async Task<QueueListResponse> GetQueueItemsAsync(ArrInstance arrInstance, int page)
|
||||||
@@ -125,7 +121,8 @@ public abstract class ArrClient : InterceptedService, IArrClient, IDryRunService
|
|||||||
using HttpRequestMessage request = new(HttpMethod.Delete, uri);
|
using HttpRequestMessage request = new(HttpMethod.Delete, uri);
|
||||||
SetApiKey(request, arrInstance.ApiKey);
|
SetApiKey(request, arrInstance.ApiKey);
|
||||||
|
|
||||||
using var _ = await ((ArrClient)Proxy).SendRequestAsync(request);
|
HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync<HttpResponseMessage>(SendRequestAsync, request);
|
||||||
|
response?.Dispose();
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
removeFromClient
|
removeFromClient
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Common.Configuration.QueueCleaner;
|
|||||||
using Domain.Models.Arr;
|
using Domain.Models.Arr;
|
||||||
using Domain.Models.Arr.Queue;
|
using Domain.Models.Arr.Queue;
|
||||||
using Domain.Models.Lidarr;
|
using Domain.Models.Lidarr;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.Arr.Interfaces;
|
using Infrastructure.Verticals.Arr.Interfaces;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -15,18 +16,14 @@ namespace Infrastructure.Verticals.Arr;
|
|||||||
|
|
||||||
public class LidarrClient : ArrClient, ILidarrClient
|
public class LidarrClient : ArrClient, ILidarrClient
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
|
||||||
public LidarrClient()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public LidarrClient(
|
public LidarrClient(
|
||||||
ILogger<LidarrClient> logger,
|
ILogger<LidarrClient> logger,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IOptions<LoggingConfig> loggingConfig,
|
IOptions<LoggingConfig> loggingConfig,
|
||||||
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
||||||
IStriker striker
|
IStriker striker,
|
||||||
) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker)
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker, dryRunInterceptor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +61,8 @@ public class LidarrClient : ArrClient, ILidarrClient
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var _ = await ((LidarrClient)Proxy).SendRequestAsync(request);
|
HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync<HttpResponseMessage>(SendRequestAsync, request);
|
||||||
|
response?.Dispose();
|
||||||
|
|
||||||
_logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext));
|
_logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Common.Configuration.QueueCleaner;
|
|||||||
using Domain.Models.Arr;
|
using Domain.Models.Arr;
|
||||||
using Domain.Models.Arr.Queue;
|
using Domain.Models.Arr.Queue;
|
||||||
using Domain.Models.Radarr;
|
using Domain.Models.Radarr;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.Arr.Interfaces;
|
using Infrastructure.Verticals.Arr.Interfaces;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -15,18 +16,14 @@ namespace Infrastructure.Verticals.Arr;
|
|||||||
|
|
||||||
public class RadarrClient : ArrClient, IRadarrClient
|
public class RadarrClient : ArrClient, IRadarrClient
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
|
||||||
public RadarrClient()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public RadarrClient(
|
public RadarrClient(
|
||||||
ILogger<ArrClient> logger,
|
ILogger<ArrClient> logger,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IOptions<LoggingConfig> loggingConfig,
|
IOptions<LoggingConfig> loggingConfig,
|
||||||
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
||||||
IStriker striker
|
IStriker striker,
|
||||||
) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker)
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker, dryRunInterceptor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +69,8 @@ public class RadarrClient : ArrClient, IRadarrClient
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var _ = await ((RadarrClient)Proxy).SendRequestAsync(request);
|
HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync<HttpResponseMessage>(SendRequestAsync, request);
|
||||||
|
response?.Dispose();
|
||||||
|
|
||||||
_logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext));
|
_logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Common.Configuration.QueueCleaner;
|
|||||||
using Domain.Models.Arr;
|
using Domain.Models.Arr;
|
||||||
using Domain.Models.Arr.Queue;
|
using Domain.Models.Arr.Queue;
|
||||||
using Domain.Models.Sonarr;
|
using Domain.Models.Sonarr;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.Arr.Interfaces;
|
using Infrastructure.Verticals.Arr.Interfaces;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -16,18 +17,14 @@ namespace Infrastructure.Verticals.Arr;
|
|||||||
|
|
||||||
public class SonarrClient : ArrClient, ISonarrClient
|
public class SonarrClient : ArrClient, ISonarrClient
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
|
||||||
public SonarrClient()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public SonarrClient(
|
public SonarrClient(
|
||||||
ILogger<SonarrClient> logger,
|
ILogger<SonarrClient> logger,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IOptions<LoggingConfig> loggingConfig,
|
IOptions<LoggingConfig> loggingConfig,
|
||||||
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
||||||
IStriker striker
|
IStriker striker,
|
||||||
) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker)
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker, dryRunInterceptor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +65,9 @@ public class SonarrClient : ArrClient, ISonarrClient
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var _ = await ((SonarrClient)Proxy).SendRequestAsync(request);
|
HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync<HttpResponseMessage>(SendRequestAsync, request);
|
||||||
|
response?.Dispose();
|
||||||
|
|
||||||
_logger.LogInformation("{log}", GetSearchLog(command.SearchType, arrInstance.Url, command, true, logContext));
|
_logger.LogInformation("{log}", GetSearchLog(command.SearchType, arrInstance.Url, command, true, logContext));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public sealed class ContentBlocker : GenericHandler
|
|||||||
ArrQueueIterator arrArrQueueIterator,
|
ArrQueueIterator arrArrQueueIterator,
|
||||||
BlocklistProvider blocklistProvider,
|
BlocklistProvider blocklistProvider,
|
||||||
DownloadServiceFactory downloadServiceFactory,
|
DownloadServiceFactory downloadServiceFactory,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier
|
||||||
) : base(
|
) : base(
|
||||||
logger, downloadClientConfig,
|
logger, downloadClientConfig,
|
||||||
sonarrConfig, radarrConfig, lidarrConfig,
|
sonarrConfig, radarrConfig, lidarrConfig,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public sealed class DownloadCleaner : GenericHandler
|
|||||||
LidarrClient lidarrClient,
|
LidarrClient lidarrClient,
|
||||||
ArrQueueIterator arrArrQueueIterator,
|
ArrQueueIterator arrArrQueueIterator,
|
||||||
DownloadServiceFactory downloadServiceFactory,
|
DownloadServiceFactory downloadServiceFactory,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier
|
||||||
) : base(
|
) : base(
|
||||||
logger, downloadClientConfig,
|
logger, downloadClientConfig,
|
||||||
sonarrConfig, radarrConfig, lidarrConfig,
|
sonarrConfig, radarrConfig, lidarrConfig,
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ using Common.Configuration.DownloadClient;
|
|||||||
using Common.Configuration.QueueCleaner;
|
using Common.Configuration.QueueCleaner;
|
||||||
using Domain.Enums;
|
using Domain.Enums;
|
||||||
using Domain.Models.Deluge.Response;
|
using Domain.Models.Deluge.Response;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.ContentBlocker;
|
using Infrastructure.Verticals.ContentBlocker;
|
||||||
using Infrastructure.Verticals.Context;
|
using Infrastructure.Verticals.Context;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
using Infrastructure.Verticals.Notifications;
|
using Infrastructure.Verticals.Notifications;
|
||||||
using MassTransit.Configuration;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@@ -22,11 +22,6 @@ public class DelugeService : DownloadService, IDelugeService
|
|||||||
{
|
{
|
||||||
private readonly DelugeClient _client;
|
private readonly DelugeClient _client;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public DelugeService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public DelugeService(
|
public DelugeService(
|
||||||
ILogger<DelugeService> logger,
|
ILogger<DelugeService> logger,
|
||||||
IOptions<DelugeConfig> config,
|
IOptions<DelugeConfig> config,
|
||||||
@@ -37,8 +32,12 @@ public class DelugeService : DownloadService, IDelugeService
|
|||||||
IMemoryCache cache,
|
IMemoryCache cache,
|
||||||
IFilenameEvaluator filenameEvaluator,
|
IFilenameEvaluator filenameEvaluator,
|
||||||
IStriker striker,
|
IStriker striker,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier,
|
||||||
) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier)
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
) : base(
|
||||||
|
logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache,
|
||||||
|
filenameEvaluator, striker, notifier, dryRunInterceptor
|
||||||
|
)
|
||||||
{
|
{
|
||||||
config.Value.Validate();
|
config.Value.Validate();
|
||||||
_client = new (config, httpClientFactory);
|
_client = new (config, httpClientFactory);
|
||||||
@@ -190,7 +189,7 @@ public class DelugeService : DownloadService, IDelugeService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ((DelugeService)Proxy).ChangeFilesPriority(hash, sortedPriorities);
|
await _dryRunInterceptor.InterceptAsync(ChangeFilesPriority, hash, sortedPriorities);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -245,8 +244,8 @@ public class DelugeService : DownloadService, IDelugeService
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ((DelugeService)Proxy).DeleteDownload(download.Hash);
|
await _dryRunInterceptor.InterceptAsync(DeleteDownload, download.Hash);
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"download cleaned | {reason} reached | {name}",
|
"download cleaned | {reason} reached | {name}",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ using Microsoft.Extensions.Options;
|
|||||||
|
|
||||||
namespace Infrastructure.Verticals.DownloadClient;
|
namespace Infrastructure.Verticals.DownloadClient;
|
||||||
|
|
||||||
public abstract class DownloadService : InterceptedService, IDownloadService
|
public abstract class DownloadService : IDownloadService
|
||||||
{
|
{
|
||||||
protected readonly ILogger<DownloadService> _logger;
|
protected readonly ILogger<DownloadService> _logger;
|
||||||
protected readonly QueueCleanerConfig _queueCleanerConfig;
|
protected readonly QueueCleanerConfig _queueCleanerConfig;
|
||||||
@@ -28,15 +28,9 @@ public abstract class DownloadService : InterceptedService, IDownloadService
|
|||||||
protected readonly IFilenameEvaluator _filenameEvaluator;
|
protected readonly IFilenameEvaluator _filenameEvaluator;
|
||||||
protected readonly IStriker _striker;
|
protected readonly IStriker _striker;
|
||||||
protected readonly MemoryCacheEntryOptions _cacheOptions;
|
protected readonly MemoryCacheEntryOptions _cacheOptions;
|
||||||
protected readonly NotificationPublisher _notifier;
|
protected readonly INotificationPublisher _notifier;
|
||||||
|
protected readonly IDryRunInterceptor _dryRunInterceptor;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor to be used by interceptors.
|
|
||||||
/// </summary>
|
|
||||||
protected DownloadService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DownloadService(
|
protected DownloadService(
|
||||||
ILogger<DownloadService> logger,
|
ILogger<DownloadService> logger,
|
||||||
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
IOptions<QueueCleanerConfig> queueCleanerConfig,
|
||||||
@@ -45,7 +39,9 @@ public abstract class DownloadService : InterceptedService, IDownloadService
|
|||||||
IMemoryCache cache,
|
IMemoryCache cache,
|
||||||
IFilenameEvaluator filenameEvaluator,
|
IFilenameEvaluator filenameEvaluator,
|
||||||
IStriker striker,
|
IStriker striker,
|
||||||
NotificationPublisher notifier)
|
INotificationPublisher notifier,
|
||||||
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_queueCleanerConfig = queueCleanerConfig.Value;
|
_queueCleanerConfig = queueCleanerConfig.Value;
|
||||||
@@ -55,6 +51,7 @@ public abstract class DownloadService : InterceptedService, IDownloadService
|
|||||||
_filenameEvaluator = filenameEvaluator;
|
_filenameEvaluator = filenameEvaluator;
|
||||||
_striker = striker;
|
_striker = striker;
|
||||||
_notifier = notifier;
|
_notifier = notifier;
|
||||||
|
_dryRunInterceptor = dryRunInterceptor;
|
||||||
_cacheOptions = new MemoryCacheEntryOptions()
|
_cacheOptions = new MemoryCacheEntryOptions()
|
||||||
.SetSlidingExpiration(StaticConfiguration.TriggerValue + Constants.CacheLimitBuffer);
|
.SetSlidingExpiration(StaticConfiguration.TriggerValue + Constants.CacheLimitBuffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Text.RegularExpressions;
|
|||||||
using Common.Configuration.ContentBlocker;
|
using Common.Configuration.ContentBlocker;
|
||||||
using Common.Configuration.DownloadCleaner;
|
using Common.Configuration.DownloadCleaner;
|
||||||
using Common.Configuration.QueueCleaner;
|
using Common.Configuration.QueueCleaner;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.ContentBlocker;
|
using Infrastructure.Verticals.ContentBlocker;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
using Infrastructure.Verticals.Notifications;
|
using Infrastructure.Verticals.Notifications;
|
||||||
@@ -14,12 +15,7 @@ namespace Infrastructure.Verticals.DownloadClient;
|
|||||||
|
|
||||||
public class DummyDownloadService : DownloadService
|
public class DummyDownloadService : DownloadService
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
public DummyDownloadService(ILogger<DownloadService> logger, IOptions<QueueCleanerConfig> queueCleanerConfig, IOptions<ContentBlockerConfig> contentBlockerConfig, IOptions<DownloadCleanerConfig> downloadCleanerConfig, IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, INotificationPublisher notifier, IDryRunInterceptor dryRunInterceptor) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier, dryRunInterceptor)
|
||||||
public DummyDownloadService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public DummyDownloadService(ILogger<DownloadService> logger, IOptions<QueueCleanerConfig> queueCleanerConfig, IOptions<ContentBlockerConfig> contentBlockerConfig, IOptions<DownloadCleanerConfig> downloadCleanerConfig, IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, NotificationPublisher notifier) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Infrastructure.Interceptors;
|
|||||||
|
|
||||||
namespace Infrastructure.Verticals.DownloadClient;
|
namespace Infrastructure.Verticals.DownloadClient;
|
||||||
|
|
||||||
public interface IDownloadService : IDisposable, IDryRunService
|
public interface IDownloadService : IDisposable
|
||||||
{
|
{
|
||||||
public Task LoginAsync();
|
public Task LoginAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
namespace Infrastructure.Verticals.DownloadClient.QBittorrent;
|
namespace Infrastructure.Verticals.DownloadClient.QBittorrent;
|
||||||
|
|
||||||
public interface IQBitService : IDownloadService
|
public interface IQBitService : IDownloadService, IDisposable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ using Common.Configuration.DownloadClient;
|
|||||||
using Common.Configuration.QueueCleaner;
|
using Common.Configuration.QueueCleaner;
|
||||||
using Common.Helpers;
|
using Common.Helpers;
|
||||||
using Domain.Enums;
|
using Domain.Enums;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.ContentBlocker;
|
using Infrastructure.Verticals.ContentBlocker;
|
||||||
using Infrastructure.Verticals.Context;
|
using Infrastructure.Verticals.Context;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
@@ -24,11 +25,6 @@ public class QBitService : DownloadService, IQBitService
|
|||||||
private readonly QBitConfig _config;
|
private readonly QBitConfig _config;
|
||||||
private readonly QBittorrentClient _client;
|
private readonly QBittorrentClient _client;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public QBitService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public QBitService(
|
public QBitService(
|
||||||
ILogger<QBitService> logger,
|
ILogger<QBitService> logger,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
@@ -39,8 +35,12 @@ public class QBitService : DownloadService, IQBitService
|
|||||||
IMemoryCache cache,
|
IMemoryCache cache,
|
||||||
IFilenameEvaluator filenameEvaluator,
|
IFilenameEvaluator filenameEvaluator,
|
||||||
IStriker striker,
|
IStriker striker,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier,
|
||||||
) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier)
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
) : base(
|
||||||
|
logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache,
|
||||||
|
filenameEvaluator, striker, notifier, dryRunInterceptor
|
||||||
|
)
|
||||||
{
|
{
|
||||||
_config = config.Value;
|
_config = config.Value;
|
||||||
_config.Validate();
|
_config.Validate();
|
||||||
@@ -200,7 +200,7 @@ public class QBitService : DownloadService, IQBitService
|
|||||||
|
|
||||||
foreach (int fileIndex in unwantedFiles)
|
foreach (int fileIndex in unwantedFiles)
|
||||||
{
|
{
|
||||||
await ((QBitService)Proxy).SkipFile(hash, fileIndex);
|
await _dryRunInterceptor.InterceptAsync(SkipFile, hash, fileIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -272,7 +272,7 @@ public class QBitService : DownloadService, IQBitService
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ((QBitService)Proxy).DeleteDownload(download.Hash);
|
await _dryRunInterceptor.InterceptAsync(DeleteDownload, download.Hash);
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"download cleaned | {reason} reached | {name}",
|
"download cleaned | {reason} reached | {name}",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Common.Configuration.DownloadClient;
|
|||||||
using Common.Configuration.QueueCleaner;
|
using Common.Configuration.QueueCleaner;
|
||||||
using Common.Helpers;
|
using Common.Helpers;
|
||||||
using Domain.Enums;
|
using Domain.Enums;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.ContentBlocker;
|
using Infrastructure.Verticals.ContentBlocker;
|
||||||
using Infrastructure.Verticals.Context;
|
using Infrastructure.Verticals.Context;
|
||||||
using Infrastructure.Verticals.ItemStriker;
|
using Infrastructure.Verticals.ItemStriker;
|
||||||
@@ -26,11 +27,6 @@ public class TransmissionService : DownloadService, ITransmissionService
|
|||||||
private readonly Client _client;
|
private readonly Client _client;
|
||||||
private TorrentInfo[]? _torrentsCache;
|
private TorrentInfo[]? _torrentsCache;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public TransmissionService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransmissionService(
|
public TransmissionService(
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
ILogger<TransmissionService> logger,
|
ILogger<TransmissionService> logger,
|
||||||
@@ -41,8 +37,12 @@ public class TransmissionService : DownloadService, ITransmissionService
|
|||||||
IMemoryCache cache,
|
IMemoryCache cache,
|
||||||
IFilenameEvaluator filenameEvaluator,
|
IFilenameEvaluator filenameEvaluator,
|
||||||
IStriker striker,
|
IStriker striker,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier,
|
||||||
) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier)
|
IDryRunInterceptor dryRunInterceptor
|
||||||
|
) : base(
|
||||||
|
logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache,
|
||||||
|
filenameEvaluator, striker, notifier, dryRunInterceptor
|
||||||
|
)
|
||||||
{
|
{
|
||||||
_config = config.Value;
|
_config = config.Value;
|
||||||
_config.Validate();
|
_config.Validate();
|
||||||
@@ -174,8 +174,8 @@ public class TransmissionService : DownloadService, ITransmissionService
|
|||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("changing priorities | torrent {hash}", hash);
|
_logger.LogDebug("changing priorities | torrent {hash}", hash);
|
||||||
|
|
||||||
await ((TransmissionService)Proxy).SetUnwantedFiles(torrent.Id, unwantedFiles.ToArray());
|
await _dryRunInterceptor.InterceptAsync(SetUnwantedFiles, torrent.Id, unwantedFiles.ToArray());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ public class TransmissionService : DownloadService, ITransmissionService
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ((TransmissionService)Proxy).RemoveDownloadAsync(download.Id);
|
await _dryRunInterceptor.InterceptAsync(RemoveDownloadAsync, download.Id);
|
||||||
|
|
||||||
_logger.LogInformation(
|
_logger.LogInformation(
|
||||||
"download cleaned | {reason} reached | {name}",
|
"download cleaned | {reason} reached | {name}",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Common.Helpers;
|
using Common.Helpers;
|
||||||
using Domain.Enums;
|
using Domain.Enums;
|
||||||
using Infrastructure.Helpers;
|
using Infrastructure.Helpers;
|
||||||
|
using Infrastructure.Interceptors;
|
||||||
using Infrastructure.Verticals.Context;
|
using Infrastructure.Verticals.Context;
|
||||||
using Infrastructure.Verticals.Notifications;
|
using Infrastructure.Verticals.Notifications;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
@@ -13,13 +14,15 @@ public sealed class Striker : IStriker
|
|||||||
private readonly ILogger<Striker> _logger;
|
private readonly ILogger<Striker> _logger;
|
||||||
private readonly IMemoryCache _cache;
|
private readonly IMemoryCache _cache;
|
||||||
private readonly MemoryCacheEntryOptions _cacheOptions;
|
private readonly MemoryCacheEntryOptions _cacheOptions;
|
||||||
private readonly NotificationPublisher _notifier;
|
private readonly INotificationPublisher _notifier;
|
||||||
|
private readonly IDryRunInterceptor _dryRunInterceptor;
|
||||||
|
|
||||||
public Striker(ILogger<Striker> logger, IMemoryCache cache, NotificationPublisher notifier)
|
public Striker(ILogger<Striker> logger, IMemoryCache cache, INotificationPublisher notifier, IDryRunInterceptor dryRunInterceptor)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
_notifier = notifier;
|
_notifier = notifier;
|
||||||
|
_dryRunInterceptor = dryRunInterceptor;
|
||||||
_cacheOptions = new MemoryCacheEntryOptions()
|
_cacheOptions = new MemoryCacheEntryOptions()
|
||||||
.SetSlidingExpiration(StaticConfiguration.TriggerValue + Constants.CacheLimitBuffer);
|
.SetSlidingExpiration(StaticConfiguration.TriggerValue + Constants.CacheLimitBuffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public abstract class GenericHandler : IHandler, IDisposable
|
|||||||
protected readonly ILidarrClient _lidarrClient;
|
protected readonly ILidarrClient _lidarrClient;
|
||||||
protected readonly ArrQueueIterator _arrArrQueueIterator;
|
protected readonly ArrQueueIterator _arrArrQueueIterator;
|
||||||
protected readonly IDownloadService _downloadService;
|
protected readonly IDownloadService _downloadService;
|
||||||
protected readonly NotificationPublisher _notifier;
|
protected readonly INotificationPublisher _notifier;
|
||||||
|
|
||||||
protected GenericHandler(
|
protected GenericHandler(
|
||||||
ILogger<GenericHandler> logger,
|
ILogger<GenericHandler> logger,
|
||||||
@@ -37,7 +37,7 @@ public abstract class GenericHandler : IHandler, IDisposable
|
|||||||
ILidarrClient lidarrClient,
|
ILidarrClient lidarrClient,
|
||||||
ArrQueueIterator arrArrQueueIterator,
|
ArrQueueIterator arrArrQueueIterator,
|
||||||
DownloadServiceFactory downloadServiceFactory,
|
DownloadServiceFactory downloadServiceFactory,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Domain.Enums;
|
||||||
|
|
||||||
|
namespace Infrastructure.Verticals.Notifications;
|
||||||
|
|
||||||
|
public interface INotificationPublisher
|
||||||
|
{
|
||||||
|
Task NotifyStrike(StrikeType strikeType, int strikeCount);
|
||||||
|
|
||||||
|
Task NotifyQueueItemDeleted(bool removeFromClient, DeleteReason reason);
|
||||||
|
|
||||||
|
Task NotifyDownloadCleaned(double ratio, TimeSpan seedingTime, string categoryName, CleanReason reason);
|
||||||
|
}
|
||||||
@@ -12,25 +12,19 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace Infrastructure.Verticals.Notifications;
|
namespace Infrastructure.Verticals.Notifications;
|
||||||
|
|
||||||
public class NotificationPublisher : InterceptedService, IDryRunService
|
public class NotificationPublisher : INotificationPublisher
|
||||||
{
|
{
|
||||||
private readonly ILogger<NotificationPublisher> _logger;
|
private readonly ILogger<INotificationPublisher> _logger;
|
||||||
private readonly IBus _messageBus;
|
private readonly IBus _messageBus;
|
||||||
|
private readonly IDryRunInterceptor _dryRunInterceptor;
|
||||||
/// <summary>
|
|
||||||
/// Constructor to be used by interceptors.
|
public NotificationPublisher(ILogger<INotificationPublisher> logger, IBus messageBus, IDryRunInterceptor dryRunInterceptor)
|
||||||
/// </summary>
|
|
||||||
public NotificationPublisher()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public NotificationPublisher(ILogger<NotificationPublisher> logger, IBus messageBus)
|
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_messageBus = messageBus;
|
_messageBus = messageBus;
|
||||||
|
_dryRunInterceptor = dryRunInterceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DryRunSafeguard]
|
|
||||||
public virtual async Task NotifyStrike(StrikeType strikeType, int strikeCount)
|
public virtual async Task NotifyStrike(StrikeType strikeType, int strikeCount)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -54,10 +48,10 @@ public class NotificationPublisher : InterceptedService, IDryRunService
|
|||||||
switch (strikeType)
|
switch (strikeType)
|
||||||
{
|
{
|
||||||
case StrikeType.Stalled:
|
case StrikeType.Stalled:
|
||||||
await _messageBus.Publish(notification.Adapt<StalledStrikeNotification>());
|
await _dryRunInterceptor.InterceptAsync(Notify<StalledStrikeNotification>, notification.Adapt<StalledStrikeNotification>());
|
||||||
break;
|
break;
|
||||||
case StrikeType.ImportFailed:
|
case StrikeType.ImportFailed:
|
||||||
await _messageBus.Publish(notification.Adapt<FailedImportStrikeNotification>());
|
await _dryRunInterceptor.InterceptAsync(Notify<FailedImportStrikeNotification>, notification.Adapt<FailedImportStrikeNotification>());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +61,6 @@ public class NotificationPublisher : InterceptedService, IDryRunService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[DryRunSafeguard]
|
|
||||||
public virtual async Task NotifyQueueItemDeleted(bool removeFromClient, DeleteReason reason)
|
public virtual async Task NotifyQueueItemDeleted(bool removeFromClient, DeleteReason reason)
|
||||||
{
|
{
|
||||||
QueueRecord record = ContextProvider.Get<QueueRecord>(nameof(QueueRecord));
|
QueueRecord record = ContextProvider.Get<QueueRecord>(nameof(QueueRecord));
|
||||||
@@ -86,10 +79,9 @@ public class NotificationPublisher : InterceptedService, IDryRunService
|
|||||||
Fields = [new() { Title = "Removed from download client?", Text = removeFromClient ? "Yes" : "No" }]
|
Fields = [new() { Title = "Removed from download client?", Text = removeFromClient ? "Yes" : "No" }]
|
||||||
};
|
};
|
||||||
|
|
||||||
await _messageBus.Publish(notification);
|
await _dryRunInterceptor.InterceptAsync(Notify<QueueItemDeletedNotification>, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DryRunSafeguard]
|
|
||||||
public virtual async Task NotifyDownloadCleaned(double ratio, TimeSpan seedingTime, string categoryName, CleanReason reason)
|
public virtual async Task NotifyDownloadCleaned(double ratio, TimeSpan seedingTime, string categoryName, CleanReason reason)
|
||||||
{
|
{
|
||||||
DownloadCleanedNotification notification = new()
|
DownloadCleanedNotification notification = new()
|
||||||
@@ -106,7 +98,13 @@ public class NotificationPublisher : InterceptedService, IDryRunService
|
|||||||
Level = NotificationLevel.Important
|
Level = NotificationLevel.Important
|
||||||
};
|
};
|
||||||
|
|
||||||
await _messageBus.Publish(notification);
|
await _dryRunInterceptor.InterceptAsync(Notify<DownloadCleanedNotification>, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DryRunSafeguard]
|
||||||
|
private Task Notify<T>(T message) where T: notnull
|
||||||
|
{
|
||||||
|
return _messageBus.Publish(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Uri GetImageFromContext(QueueRecord record, InstanceType instanceType) =>
|
private static Uri GetImageFromContext(QueueRecord record, InstanceType instanceType) =>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public sealed class QueueCleaner : GenericHandler
|
|||||||
LidarrClient lidarrClient,
|
LidarrClient lidarrClient,
|
||||||
ArrQueueIterator arrArrQueueIterator,
|
ArrQueueIterator arrArrQueueIterator,
|
||||||
DownloadServiceFactory downloadServiceFactory,
|
DownloadServiceFactory downloadServiceFactory,
|
||||||
NotificationPublisher notifier
|
INotificationPublisher notifier
|
||||||
) : base(
|
) : base(
|
||||||
logger, downloadClientConfig,
|
logger, downloadClientConfig,
|
||||||
sonarrConfig, radarrConfig, lidarrConfig,
|
sonarrConfig, radarrConfig, lidarrConfig,
|
||||||
|
|||||||
Reference in New Issue
Block a user