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

Race condition in DI scheduler listener initialization #1117

Closed
esskar opened this issue Feb 17, 2021 · 1 comment · Fixed by #1265
Closed

Race condition in DI scheduler listener initialization #1117

esskar opened this issue Feb 17, 2021 · 1 comment · Fixed by #1265
Milestone

Comments

@esskar
Copy link

esskar commented Feb 17, 2021

Describe the bug

I implemented my custom ISchedulerListener - it does nothing, just return Task.CompletedTask for now. I register it in DI c.AddSchedulerListener<MySchedulerListener>();
Constructor is called during startup, when I schedule a job

class MyService
{

    public async Task CreateJobAsync()
    {
        var job = JobBuilder.Create<ProcessJob>()
            .WithIdentity("foo")
            .Build();
    
        var trigger = TriggerBuilder.Create()
            .WithIdentity("bar")
            .StartNow()
            .Build();

         var scheduler = await StdSchedulerFactory.GetDefaultScheduler();
         var scheduled = await scheduler.ScheduleJob(job, trigger);
    }
}

No function of my MySchedulerListener is triggered.

Then, I tried using ISchedulerFactory via DI

class MyService
{
    private readonly ISchedulerFactory _schedulerFactory;

    public MyService(ISchedulerFactory schedulerFactory)
    {
        _schedulerFactory = schedulerFactory ?? throw new ArgumentNullException(nameof(schedulerFactory));
    }

    public async Task CreateJobAsync()
    {
        var job = JobBuilder.Create<ProcessJob>()
            .WithIdentity("foo")
            .Build();
    
        var trigger = TriggerBuilder.Create()
            .WithIdentity("bar")
            .StartNow()
            .Build();

         var scheduler = await _schedulerFactory.GetScheduler();
         var scheduled = await scheduler.ScheduleJob(job, trigger);
    }
}

Now, the constructor of MySchedulerListener is called a second time when I call _schedulerFactory.GetScheduler(); and the functions of MySchedulerListener are called twice.

Version used

3.2.4 and using .NET 5.0

Expected behavior

From looking at the code, I understand that StdSchedulerFactory.GetDefaultScheduler() will not work as - internally - it is not using any DI, but I expected that ISchedulerFactory would only trigger my MySchedulerListener once.

@lahma
Copy link
Member

lahma commented Aug 1, 2021

One shouldn't mix and max "regular" scheduler building and DI, like you've noticed. Such double invocation could be a result of race condition in scheduler initialization (two threads calling schedulerFactor.GetScheduler() at the same time). I've added synchronization primitive to prevent that.

@lahma lahma changed the title Custom ISchedulerListener not called or called twice Race condition in DI scheduler listener initialization Aug 1, 2021
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

Successfully merging a pull request may close this issue.

2 participants