Watcher
This commit is contained in:
parent
8909fb8b57
commit
762bf513f4
2 changed files with 102 additions and 14 deletions
6
src/pdns-dhcp/Kea/KeaDhcpLeaseFileReader.cs
Normal file
6
src/pdns-dhcp/Kea/KeaDhcpLeaseFileReader.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace pdns_dhcp.Kea;
|
||||
|
||||
public class KeaDhcpLeaseFileReader
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,18 @@
|
|||
using System.Threading.Channels;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using pdns_dhcp.Options;
|
||||
|
||||
namespace pdns_dhcp.Kea;
|
||||
|
||||
public abstract class KeaDhcpLeaseWatcher : BackgroundService
|
||||
public abstract class KeaDhcpLeaseWatcher : IHostedService
|
||||
{
|
||||
private readonly FileSystemWatcher _fsw;
|
||||
private readonly string _leaseFile;
|
||||
private Channel<FileSystemEventArgs>? _eventChannel;
|
||||
private Task? _executeTask;
|
||||
private CancellationTokenSource? _stoppingCts;
|
||||
|
||||
protected KeaDhcpServerOptions Options { get; }
|
||||
|
||||
|
|
@ -26,31 +32,107 @@ public abstract class KeaDhcpLeaseWatcher : BackgroundService
|
|||
throw new ArgumentException($"{nameof(options.Leases)} must point to a file in an existing path.", nameof(options));
|
||||
}
|
||||
|
||||
_fsw = new(leaseDirectory, leaseFile.ToString());
|
||||
_leaseFile = leaseFile.ToString();
|
||||
_fsw = new(leaseDirectory, _leaseFile);
|
||||
_fsw.Changed += OnLeaseChanged;
|
||||
_fsw.Created += OnLeaseChanged;
|
||||
_fsw.Deleted += OnLeaseChanged;
|
||||
_fsw.Renamed += OnLeaseRenamed;
|
||||
_fsw.Error += OnLeaseError;
|
||||
}
|
||||
|
||||
protected override Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
_stoppingCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
_executeTask = Reading(_stoppingCts.Token);
|
||||
return _executeTask is { IsCompleted: true } completed ? completed : Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_executeTask is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_fsw.EnableRaisingEvents = false;
|
||||
try
|
||||
{
|
||||
_stoppingCts!.Cancel();
|
||||
}
|
||||
finally
|
||||
{
|
||||
TaskCompletionSource taskCompletionSource = new();
|
||||
using (cancellationToken.Register(s => ((TaskCompletionSource)s!).SetCanceled(), taskCompletionSource))
|
||||
{
|
||||
await Task.WhenAny(_executeTask, taskCompletionSource.Task).ConfigureAwait(continueOnCapturedContext: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Reading(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
using CancellationTokenSource loopCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
|
||||
_eventChannel = Channel.CreateUnbounded<FileSystemEventArgs>();
|
||||
_fsw.EnableRaisingEvents = true;
|
||||
ValueTask reader = default;
|
||||
try
|
||||
{
|
||||
await foreach (var @event in _eventChannel.Reader.ReadAllAsync(loopCts.Token))
|
||||
{
|
||||
switch (@event)
|
||||
{
|
||||
case { ChangeType: WatcherChangeTypes.Created }:
|
||||
case RenamedEventArgs { ChangeType: WatcherChangeTypes.Renamed } renamed when renamed.Name == _leaseFile:
|
||||
reader = FileReader(loopCts.Token);
|
||||
break;
|
||||
|
||||
case { ChangeType: WatcherChangeTypes.Deleted }:
|
||||
case RenamedEventArgs { ChangeType: WatcherChangeTypes.Renamed } renamed when renamed.OldName == _leaseFile:
|
||||
loopCts.Cancel();
|
||||
break;
|
||||
|
||||
case { ChangeType: WatcherChangeTypes.Changed }:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
_eventChannel.Writer.TryComplete();
|
||||
try
|
||||
{
|
||||
await reader.ConfigureAwait(continueOnCapturedContext: false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
ValueTask FileReader(CancellationToken stoppingToken)
|
||||
{
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLeaseChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var writer = _eventChannel?.Writer;
|
||||
if (writer?.TryWrite(e) != false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var write = writer.WriteAsync(e);
|
||||
if (write.IsCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
write.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private void OnLeaseError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void OnLeaseRenamed(object sender, RenamedEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_eventChannel?.Writer.Complete(e.GetException());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue