Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asynchronous jobs don't work as expected #1074

Open
alexeyfv opened this issue Jan 8, 2025 · 0 comments
Open

Asynchronous jobs don't work as expected #1074

alexeyfv opened this issue Jan 8, 2025 · 0 comments

Comments

@alexeyfv
Copy link
Contributor

alexeyfv commented Jan 8, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant