atifaziz / NCrontab

Crontab for .NET
Apache License 2.0
913 stars 139 forks source link

Wrong next occurrance for multiple tasks #125

Closed Mazze112 closed 6 months ago

Mazze112 commented 6 months ago

I'm trying to create a list of tasks, that execute in parallel at a certain cron.

There are 5 streams:

List<Task> taskList = new List<Task>();

foreach (var config in _options)
{
    var crontabSchedule = CrontabSchedule.Parse(config.Cron,
        new CrontabSchedule.ParseOptions
        {
            IncludingSeconds = true
        });

    DateTime nextOccurrence = crontabSchedule.GetNextOccurrence(DateTime.Now);

    taskList.Add(Task.Run(async () =>
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            var delay = Math.Max(0,
                (int)nextOccurrence.Subtract(DateTime.Now).TotalMilliseconds);

            await Task.Delay(delay, cancellationToken);

            _logger.LogInformation($"Stream {config.StreamName} start.");

            await DoWork();

            _logger.LogInformation($"Stream {config.StreamName} end.");

            nextOccurrence = crontabSchedule.GetNextOccurrence(DateTime.Now);
        }
    }, cancellationToken));
}

if (taskList is not null && taskList.Any())
{
    await Task.WhenAll(taskList);
}

I was expecting this kind of execution flow

[2024/04/30 11:03:00 INF] Stream STREAM1 start. 
[2024/04/30 11:03:00 INF] Stream STREAM1 end. 
[2024/04/30 11:03:00 INF] Stream STREAM1 next occurrence 5/1/2024 11:03:00 AM

[2024/04/30 11:04:00 INF] Stream STREAM2 start. 
[2024/04/30 11:04:00 INF] Stream STREAM2 end. 
[2024/04/30 11:04:00 INF] Stream STREAM2 next occurrence 5/1/2024 11:04:00 AM

[2024/04/30 11:05:00 INF] Stream STREAM3 start. 
[2024/04/30 11:05:00 INF] Stream STREAM3 end. 
[2024/04/30 11:05:00 INF] Stream STREAM3 next occurrence 5/1/2024 11:05:00 AM 

Instead I get these

[2024/04/30 11:03:00 INF] Stream STREAM1 start. 
[2024/04/30 11:03:00 INF] Stream STREAM1 end. 
[2024/04/30 11:03:00 INF] Stream STREAM1 next occurrence 5/1/2024 11:03:05 AM

[2024/04/30 11:03:00 INF] Stream STREAM2 start. 
[2024/04/30 11:03:00 INF] Stream STREAM2 end. 
[2024/04/30 11:03:00 INF] Stream STREAM2 next occurrence 4/30/2024 11:04:00 AM
[2024/04/30 11:04:00 INF] Stream STREAM2 start. 
[2024/04/30 11:04:00 INF] Stream STREAM2 end. 
[2024/04/30 11:04:00 INF] Stream STREAM2 next occurrence 5/1/2024 11:04:00 AM

[2024/04/30 11:05:00 INF] Stream STREAM3 start. 
[2024/04/30 11:05:00 INF] Stream STREAM3 end. 
[2024/04/30 11:05:00 INF] Stream STREAM3 next occurrence 5/1/2024 11:05:00 AM 

I don't understand why stream 2 is executed two times, at the scheduled cron and 1 second before the schedule, it doesn't happen all the time or for certain stream.

Thank you

atifaziz commented 6 months ago

CrontabSchedule doesn't itself do any scheduling. Its GetNextOccurrence method just computes the next occurrence based on a given base time so I'm afraid there must be something wrong in your logic/code. If you're convinced otherwise then you'll need to share a stand-alone, runnable and minimal code that demonstrates the issue so I can run it on my end and try to reproduce it. Right now, your logs don't match the code you shared (e.g. there's nothing logging the next occurrence as I see it) so all bets are off.

atifaziz commented 6 months ago

Closing as there's been no follow-up.