FilesService: used BackgroundService

This commit is contained in:
Maksim Chegulov 2022-02-24 12:51:12 +03:00
parent b974d15ddd
commit 04b0ac97d2
5 changed files with 136 additions and 165 deletions

View File

@ -91,8 +91,13 @@ builder.Host.ConfigureServices((hostContext, services) =>
services.AddHostedService<FeedCleanerService>();
diHelper.TryAdd<FeedCleanerService>();
services.AddHostedService<Launcher>();
diHelper.TryAdd<Launcher>();
diHelper.TryAdd<FileDataQueue>();
services.AddHostedService<ThumbnailService>();
diHelper.TryAdd<ThumbnailService>();
services.AddHostedService<ThumbnailBuilder>();
diHelper.TryAdd<ThumbnailBuilder>();
diHelper.TryAdd<AuthManager>();
diHelper.TryAdd<BaseCommonLinkUtility>();

View File

@ -112,7 +112,7 @@ internal class Builder<T>
}
finally
{
Launcher.Queue.TryRemove(fileData.FileId, out _);
FileDataQueue.Queue.TryRemove(fileData.FileId, out _);
}
}

View File

@ -14,44 +14,11 @@
*
*/
namespace ASC.Files.ThumbnailBuilder;
[Singletone(Additional = typeof(WorkerExtension))]
public class Launcher : IHostedService
{
internal static readonly ConcurrentDictionary<object, FileData<int>> Queue
= new ConcurrentDictionary<object, FileData<int>>();
private Worker _worker;
private readonly Service Service;
public Launcher(Service service, Worker worker)
{
Service = service;
_worker = worker;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_worker.Start(cancellationToken);
Service.Start();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
if (_worker != null)
{
_worker.Stop();
_worker = null;
}
if (Service != null)
{
Service.Stop();
}
return Task.CompletedTask;
}
}
namespace ASC.Files.ThumbnailBuilder;
[Singletone(Additional = typeof(WorkerExtension))]
public class FileDataQueue
{
internal static readonly ConcurrentDictionary<object, FileData<int>> Queue
= new ConcurrentDictionary<object, FileData<int>>();
}

View File

@ -14,92 +14,83 @@
*
*/
namespace ASC.Files.ThumbnailBuilder;
[Singletone]
public class Worker
{
private readonly IServiceProvider _serviceProvider;
private CancellationToken _cancellationToken;
private readonly ThumbnailSettings _thumbnailSettings;
private readonly ILog _logger;
private Timer _timer;
public Worker(
IServiceProvider serviceProvider,
IOptionsMonitor<ILog> options,
ThumbnailSettings settings)
{
_serviceProvider = serviceProvider;
_thumbnailSettings = settings;
_logger = options.Get("ASC.Files.ThumbnailBuilder");
}
public void Start(CancellationToken cancellationToken)
{
_timer = new Timer(Procedure, null, 0, Timeout.Infinite);
_cancellationToken = cancellationToken;
}
public void Stop()
{
if (_timer != null)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
_timer.Dispose();
_timer = null;
}
}
private void Procedure(object _)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
_logger.Trace("Procedure: Start.");
if (_cancellationToken.IsCancellationRequested)
{
Stop();
return;
}
//var configSection = (ConfigSection)ConfigurationManager.GetSection("thumbnailBuilder") ?? new ConfigSection();
//CommonLinkUtility.Initialize(configSection.ServerRoot, false);
var filesWithoutThumbnails = Launcher.Queue.Select(pair => pair.Value).ToList();
if (filesWithoutThumbnails.Count == 0)
{
_logger.TraceFormat("Procedure: Waiting for data. Sleep {0}.", _thumbnailSettings.LaunchFrequency);
_timer.Change(TimeSpan.FromSeconds(_thumbnailSettings.LaunchFrequency), TimeSpan.FromMilliseconds(-1));
return;
}
using (var scope = _serviceProvider.CreateScope())
{
var fileDataProvider = scope.ServiceProvider.GetService<FileDataProvider>();
var builder = scope.ServiceProvider.GetService<BuilderQueue<int>>();
var premiumTenants = fileDataProvider.GetPremiumTenants();
filesWithoutThumbnails = filesWithoutThumbnails
.OrderByDescending(fileData => Array.IndexOf(premiumTenants, fileData.TenantId))
.ToList();
builder.BuildThumbnails(filesWithoutThumbnails);
}
_logger.Trace("Procedure: Finish.");
_timer.Change(0, Timeout.Infinite);
}
}
public static class WorkerExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<FileDataProvider>();
services.TryAdd<BuilderQueue<int>>();
services.TryAdd<Builder<int>>();
}
namespace ASC.Files.ThumbnailBuilder;
[Singletone]
public class ThumbnailBuilder : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ThumbnailSettings _thumbnailSettings;
private readonly ILog _logger;
public ThumbnailBuilder(
IServiceProvider serviceProvider,
IOptionsMonitor<ILog> options,
ThumbnailSettings settings)
{
_serviceProvider = serviceProvider;
_thumbnailSettings = settings;
_logger = options.Get("ASC.Files.ThumbnailBuilder");
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.Info("Thumbnail Worker running.");
while (!stoppingToken.IsCancellationRequested)
{
await Procedure(stoppingToken);
}
_logger.Info("Thumbnail Worker is stopping.");
}
private async Task Procedure(CancellationToken stoppingToken)
{
_logger.Trace("Procedure: Start.");
if (stoppingToken.IsCancellationRequested)
{
return;
}
//var configSection = (ConfigSection)ConfigurationManager.GetSection("thumbnailBuilder") ?? new ConfigSection();
//CommonLinkUtility.Initialize(configSection.ServerRoot, false);
var filesWithoutThumbnails = FileDataQueue.Queue.Select(pair => pair.Value).ToList();
if (filesWithoutThumbnails.Count == 0)
{
_logger.TraceFormat("Procedure: Waiting for data. Sleep {0}.", _thumbnailSettings.LaunchFrequency);
await Task.Delay(TimeSpan.FromSeconds(_thumbnailSettings.LaunchFrequency), stoppingToken);
return;
}
using (var scope = _serviceProvider.CreateScope())
{
var fileDataProvider = scope.ServiceProvider.GetService<FileDataProvider>();
var builder = scope.ServiceProvider.GetService<BuilderQueue<int>>();
var premiumTenants = fileDataProvider.GetPremiumTenants();
filesWithoutThumbnails = filesWithoutThumbnails
.OrderByDescending(fileData => Array.IndexOf(premiumTenants, fileData.TenantId))
.ToList();
builder.BuildThumbnails(filesWithoutThumbnails);
}
_logger.Trace("Procedure: Finish.");
}
}
public static class WorkerExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<FileDataProvider>();
services.TryAdd<BuilderQueue<int>>();
services.TryAdd<Builder<int>>();
}
}

View File

@ -14,37 +14,45 @@
*
*/
namespace ASC.Files.ThumbnailBuilder;
[Singletone]
public class Service
{
private readonly ICacheNotify<ThumbnailRequest> _cacheNotify;
public Service(ICacheNotify<ThumbnailRequest> cacheNotify)
{
_cacheNotify = cacheNotify;
}
public void Start()
{
_cacheNotify.Subscribe(BuildThumbnails, CacheNotifyAction.Insert);
//Cache.Subscribe
}
public void Stop()
{
_cacheNotify.Unsubscribe(CacheNotifyAction.Insert);
//Cache.Subscribe
}
public void BuildThumbnails(ThumbnailRequest request)
{
foreach (var fileId in request.Files)
{
var fileData = new FileData<int>(request.Tenant, fileId, request.BaseUrl);
Launcher.Queue.TryAdd(fileId, fileData);
}
}
namespace ASC.Files.ThumbnailBuilder;
[Singletone]
public class ThumbnailService : IHostedService
{
private readonly ICacheNotify<ThumbnailRequest> _cacheNotify;
private readonly ILog _logger;
public ThumbnailService(ICacheNotify<ThumbnailRequest> cacheNotify, IOptionsMonitor<ILog> options)
{
_cacheNotify = cacheNotify;
_logger = options.Get("ASC.Files.ThumbnailService");
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.Info("Thumbnail Service running.");
_cacheNotify.Subscribe(BuildThumbnails, CacheNotifyAction.Insert);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.Info("Thumbnail Service is stopping.");
_cacheNotify.Unsubscribe(CacheNotifyAction.Insert);
return Task.CompletedTask;
}
public void BuildThumbnails(ThumbnailRequest request)
{
foreach (var fileId in request.Files)
{
var fileData = new FileData<int>(request.Tenant, fileId, request.BaseUrl);
FileDataQueue.Queue.TryAdd(fileId, fileData);
}
}
}