Skip to content

Commit

Permalink
just use Task.Delay() in conjunction with cron
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan committed Apr 10, 2024
1 parent 99c1af8 commit 81318b0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 45 deletions.
65 changes: 24 additions & 41 deletions src/Hosting/Hosting/src/Workers/CronWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
using Cronos;
using Microsoft.Extensions.Logging;

public abstract class CronWorker : Worker, IDisposable
public abstract class CronWorker : Worker
{
private readonly ILogger _logger;
private readonly Random _delayGenerator = new();
private readonly CronWorkerOption? _option;
private Timer? _timer;
private CancellationTokenSource? _cancellationTokenSource;

// Cron format: https://www.nuget.org/packages/Cronos/
protected abstract string CronSchedule { get; }
Expand All @@ -28,42 +26,36 @@ protected CronWorker(CronWorkerOption option, ILogger logger) : base(logger)
_logger = logger;
}

protected override Task ExecuteAsync(CancellationToken cancellationToken)
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
var dueTime = GetNextScheduleDelay();
if (!dueTime.HasValue)
throw new Exception("Failed to get next schedule");

_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_timer = new Timer(_ => TimerCallbackAsync(_cancellationTokenSource.Token), null, dueTime.Value, Timeout.InfiniteTimeSpan);
while (!cancellationToken.IsCancellationRequested)
{
var dueTime = GetNextScheduleDelay();
if (!dueTime.HasValue)
{
_logger.LogWarning("Failed to get next schedule");

return Task.CompletedTask;
}
// Wait for a while before retrying
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
continue;
}

private async void TimerCallbackAsync(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
return;
try
{
await Task.Delay(dueTime.Value, cancellationToken);
}
catch (OperationCanceledException)
{
return;
}

try
{
await RunAsync(cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception caught in SchedulerWorker ({WorkerName})", Name);
}
finally
{
var dueTime = GetNextScheduleDelay();
if (dueTime.HasValue)
try
{
// Reschedule the timer
_timer?.Change(dueTime.Value, Timeout.InfiniteTimeSpan);
await RunAsync(cancellationToken);
}
else
catch (Exception ex)
{
_logger.LogError("Unable to get the next schedule in SchedulerWorker ({WorkerName})", Name);
_logger.LogError(ex, "Unhandled exception caught in CronWorker ({WorkerName})", Name);
}
}
}
Expand All @@ -87,14 +79,5 @@ private async void TimerCallbackAsync(CancellationToken cancellationToken)
return delay.Add(extraDelay);
}

public void Dispose()
{
_cancellationTokenSource?.Cancel();

// Stop the timer
_timer?.Change(Timeout.Infinite, 0);
_timer?.Dispose();
}

protected abstract Task RunAsync(CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ public async Task RunAsync_RunEveryTwoSeconds()
await scheduler.StopAsync(CancellationToken.None);

Assert.True(scheduler.Counter >= 2);

scheduler.Dispose();
}

[Fact]
Expand Down Expand Up @@ -52,8 +50,6 @@ public async Task RunAsync_RunEveryTwoSeconds_return()

Assert.NotNull(scheduler.FirstExecutionTime);
Assert.True(scheduler.FirstExecutionTime.Value - currentTime > TimeSpan.FromSeconds(2));

scheduler.Dispose();
}

public class TestScheduler : CronWorker
Expand Down

0 comments on commit 81318b0

Please sign in to comment.