2
0
mirror of https://github.com/9ParsonsB/Pulsar.git synced 2025-04-05 17:39:39 -04:00
pulsar/Pulsar/Features/FileWatcherService.cs
Ben Parsons efd0b3e0c0 Journals Now processed in own thread
Some invalid journal data is now handled
Journals now use polymorphic deserialization
Added Event names to all journal events
Remove unused controllers
2024-05-24 19:30:12 +10:00

86 lines
2.5 KiB
C#

namespace Pulsar.Features;
using System.Collections.Concurrent;
using Microsoft.Extensions.FileProviders;
public class FileWatcherService(IOptions<PulsarConfiguration> options, IFileHandlerService fileHandlerService)
: IHostedService
{
private PhysicalFileProvider watcher = null!;
public Task StartAsync(CancellationToken cancellationToken)
{
if (!Directory.Exists(options.Value.JournalDirectory))
{
throw new Exception($"Directory {options.Value.JournalDirectory} does not exist.");
}
watcher = new PhysicalFileProvider(options.Value.JournalDirectory);
Watch(cancellationToken);
// read the journal directory to get the initial files
#if DEBUG
Task.Run(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
HandleFileChanged(cancellationToken);
}, cancellationToken);
#else
HandleFileChanged(cancellationToken);
#endif
return Task.CompletedTask;
}
ConcurrentDictionary<string, DateTimeOffset> FileDates = new();
private void HandleFileChanged(CancellationToken token = new())
{
var tasks = new List<Task>();
foreach (var file in watcher.GetDirectoryContents(""))
{
if (file.IsDirectory || !file.Name.EndsWith(".json") &&
!(file.Name.StartsWith(FileHandlerService.JournalLogFileNameStart) &&
file.Name.EndsWith(FileHandlerService.JournalLogFileNameEnd)))
{
return;
}
FileDates.AddOrUpdate(file.PhysicalPath, _ =>
{
tasks.Add(Task.Run(() => fileHandlerService.HandleFile(file.PhysicalPath, token), token));
return file.LastModified;
}, (_, existing) =>
{
if (existing != file.LastModified)
{
tasks.Add(Task.Run(() => fileHandlerService.HandleFile(file.PhysicalPath, token), token));
}
return file.LastModified;
});
}
Watch(token);
Task.WaitAll(tasks.ToArray(), token);
}
private void Watch(CancellationToken token)
{
void Handle(object? _)
{
HandleFileChanged(token);
}
watcher.Watch("*.*").RegisterChangeCallback(Handle, null);
}
public Task StopAsync(CancellationToken cancellationToken)
{
watcher.Dispose();
return Task.CompletedTask;
}
}