Search code examples
c#.netquartz-schedulerquartz.netquartz

Quartz .NET how to get the scheduler using DI integration to clear the scheduler before initializing jobs and triggers


Situation

I have implemented Quartz using this DI integration example. The configuration makes sure that when the application starts, the jobs and triggers overwrite the existing jobs and triggers.

Problem

BUT when I want to rename a job or trigger, it won't overwrite the existing record and add a new record. Thus, the same job or trigger (only with a different name) is twice in the DB.

Desired solution

If I could trigger scheduler.clear() before adding the jobs and triggers within the services.addQuartz function, that would be (in my opinion) the desired solution. But I can't seem to figure out how to do this using DI integration.


Solution

  • I found it! Getting the scheduler within the AddQuartz passing the properties, just initialized within the function like this:

    services.AddQuartz(options =>
    {
        options.InterruptJobsOnShutdown = false;
        options.InterruptJobsOnShutdownWithWait = true; // only when services.AddQuartzHostedService options.WaitForJobsToComplete is also true
        options.UsePersistentStore(s =>
        {
            s.UseProperties = true;
            s.UseSqlServer(sqlServer =>
            {
                sqlServer.ConnectionString = configuration["ConnectionString"];
                sqlServer.TablePrefix = "Qrtz_";
            });
            s.UseNewtonsoftJsonSerializer();
        });
    
        try
        {
            Task.Run(async () =>
            {
               // Clear DB before adding the jobs and triggers
               ISchedulerFactory schedulerFactory = new StdSchedulerFactory(options.Properties);
               IScheduler scheduler = await schedulerFactory.GetScheduler();
               await scheduler.Clear();
               // Call shutdown to clear the configuration of the scheduler, otherwhise the DI scheduler will not be initialized
               await scheduler.Shutdown();
            }).Wait();
        }
        catch (AggregateException)
        {
            // Do nothing, this happens when the application is starting for the first time and the tables are not created yet
        }
    
        if (assemblies?.Any() == true)
        {
            foreach (Assembly assembly in assemblies)
            {
                IEnumerable<Type> jobTypes = assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IJobExtenstions)));
    
                foreach (Type jobType in jobTypes)
                {
                    IJobExtenstions jobInstance = FormatterServices.GetUninitializedObject(jobType) as IJobExtenstions;
                    options.AddJob(jobInstance.GetType(), jobInstance.JobKey);
                    options.AddTrigger(jobInstance.TriggerConfigurator);
                }
            }
        };
    });