Asynchronous jobs don't work as expected
Hi,
I think I found two potential issues in the jobs functionality. But maybe I don’t understand something. Please let me know if I’m wrong.
Code snippets
There is a test aggregate.
class Test(TestId id) : AggregateRoot<Test, TestId>(id), IEmit<Pinged>
{
public Task Ping()
{
Console.WriteLine("Ping");
Emit(new Pinged());
return Task.CompletedTask;
}
public void Apply(Pinged aggregateEvent) { }
}
There is also a subscriber to Pinged event. The subscriber schedules a job with 5 sec delay.
class TestSubscribers(IJobScheduler jobScheduler) : ISubscribeAsynchronousTo<Test, TestId, Pinged>
{
public async Task HandleAsync(IDomainEvent<Test, TestId, Pinged> domainEvent, CancellationToken cancellationToken)
{
var job = new PingJob() { TestId = domainEvent.AggregateIdentity };
Console.WriteLine("Schedule job");
await jobScheduler.ScheduleAsync(job, TimeSpan.FromSeconds(5), cancellationToken);
}
}
The job just pings the aggregate. And the whole process repeats.
class PingJob : IJob
{
public required TestId TestId { get; init; }
public async Task ExecuteAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken)
{
Console.WriteLine("Job started at: {0}", DateTimeOffset.Now);
await serviceProvider
.GetRequiredService<IAggregateStore>()
.UpdateAsync<Test, TestId>(TestId, TestId.New, (a, _) => a.Ping(), cancellationToken);
}
}
Full example is here.
1st issue
From the code above, I expect that the job will be started after 5 sec delay. But in my case, it starts only after 15 sec.
dotnet run
Ping
Hangfire Server started. Press ENTER to exit...
Schedule job
Job started at: 08.01.2025 19:18:42 +01:00
Ping
Schedule job
Job started at: 08.01.2025 19:18:57 +01:00
Ping
Schedule job
Job started at: 08.01.2025 19:19:12 +01:00
Ping
Schedule job
Job started at: 08.01.2025 19:19:27 +01:00
Ping
Schedule job
2nd issue
Everything works fine, if I register events, subscribers and jobs like this
// Works fine
eventFlowOptions
.AddAsynchronousSubscriber<Test, TestId, Pinged, TestSubscribers>()
.AddEvents(typeof(Pinged))
.AddJobs(typeof(PingJob));
But if I replace the code above with the following code:
// Works incorrectly
eventFlowOptions.AddDefaults(typeof(Program).Assembly);
eventFlowOptions.AddDefaults(typeof(Test).Assembly);
The output becomes like this:
dotnet run
Ping
Hangfire Server started. Press ENTER to exit...
Schedule job
Schedule job
Job started at: 08.01.2025 19:26:00 +01:00
Job started at: 08.01.2025 19:26:00 +01:00
Ping
Ping
Schedule job
Schedule job
Ping
Schedule job
Schedule job
Job started at: 08.01.2025 19:26:15 +01:00
Job started at: 08.01.2025 19:26:15 +01:00
Job started at: 08.01.2025 19:26:15 +01:00
Job started at: 08.01.2025 19:26:15 +01:00
Ping
Ping
Ping
Ping
Schedule job
Schedule job
Ping
Ping
Ping
Schedule job
Schedule job
Ping
Ping
Schedule job
Schedule job
Ping
Schedule job
Schedule job
Seems like this causes registration of the async subscriber twice.
Thanks for reporting @alexeyfv. Sorry, have been travelling with work and had loads of stuff to do.
Regarding issue 1) I expect that is how Hangfire does it, you can't expect database scheduled jobs to start within seconds. Within roughly one minute is normal (as I remember it).
Regarding issue 2) I haven't seen this before and based on how the registrations work, it shouldn't. If you can reproduce it in a test added via a PR, then it would make it easier to collaborate on. Just to make sure that there aren't any other factors affecting it.
Hello there!
We hope you are doing well. We noticed that this issue has not seen any activity in the past 90 days. We consider this issue to be stale and will be closing it within the next seven days.
If you still require assistance with this issue, please feel free to reopen it or create a new issue.
Thank you for your understanding and cooperation.
Best regards, EventFlow
Closing this as fixed by #1093. @alexeyfv let me know if something is lacking