How to add job with trigger for running Quartz.NET scheduler instance without restarting server?

亡梦爱人 提交于 2019-11-29 15:22:24

问题


Is it possible to add job with trigger for running Quartz.NET scheduler instance without restarting server?


回答1:


A fairly robust implementation with ADOJobStore is to have a custom table to store jobs and create a class that inherits from ISchedulerPlugin and IJob to create schedules for your job automatically.

Your config will look like this:

<add key="quartz.plugin.sqlquartzjobs.type" value="(JobSchedulerPlugin assembly path)" />
<add key="quartz.plugin.sqlquartzjobs.RescanCronExpression" value="0 0/5 * * * ?" /> //plugin should fire every five minutes
<add key="quartz.plugin.sqlquartzjobs.ConnectionString" value="(your connection string)" />

Your plugin/job class can look like this:

public class JobSchedulerPlugin : ISchedulerPlugin, IJob
{
        //Entry point for plugin, quartz server runs when it starts
        public void Initialize(string pluginName, IScheduler sched)
        {
            Name = pluginName;
            Scheduler = sched;
        }

        //Runs after Initialize()
        public void Start()
        {
                //schedule plugin as a job
            JobDataMap jobData = new JobDataMap();
            jobData["ConnectionString"] = ConnectionString;

            IJobDetail job = JobBuilder.Create(this.GetType())
                .WithDescription("Job to rescan jobs from SQL db")
                .WithIdentity(new JobKey(JobInitializationPluginJobName, JobInitializationPluginGroup))
                .UsingJobData(jobData)
                .Build();

             TriggerKey triggerKey = new TriggerKey(JobInitializationPluginJobTriggerName, JobInitializationPluginGroup);

             ITrigger trigger = TriggerBuilder.Create()
                 .WithCronSchedule(ConfigFileCronExpression)
                 .StartNow()
                 .WithDescription("trigger for sql job loader")
                 .WithIdentity(triggerKey)
                 .WithPriority(1)
                 .Build();

             Scheduler.ScheduleJob(job, trigger);
        }
}

Now JobSchedulerPlugin has entered a trigger into QRTZ_TRIGGERS that will fire every five minutes with highest priority. You can use it to load jobs from your custom table (let's call it QUARTZJOBS). QUARTZJOBS can contain information such as jobnames, assembly paths, dates, status, etc, anything that can be used to help you create triggers efficiently. It should also contain the cron expression to the job. This is what you can do when the trigger fires:

//Entry point of every job
public void Execute(IJobExecutionContext context)
{
    Scheduler = context.Scheduler;

    JobCollection jobs = LoadJobs(context.JobDetail.JobDataMap["ConnectionString"].ToString());
    JobsWithTriggers jobTriggers = CreateTriggers(jobs);
    SchedulerJob(jobTriggers);
}

//You can use ADO.NET or an ORM here to load job information from the the table
//and push it into a class. 
protected JobCollection LoadJobs(string connectionString);

//In this class you can create JobDetails and ITriggers for each job
//and push them into a custom class
protected JobsWithTriggers CreateTriggers(jobs);

//Finally here you can schedule the jobs
protected void ScheduleJobs(jobstriggers)

In each of the classes above you can add custom validation for making sure triggers are handled appropriately if status or cron expression changes.

With this solution the server will never need to be restarted. The plugin/job class will scan the table and act accordingly.




回答2:


What is your data store?

Here is one scenario... a little off the beaten path:

You can write a small console app (or similar) that is the "Job Populater".

You can wire it to pull job definitions from an xml file, and push them into ADO datastore (sql server).

Here is my quartz config to do this:

<quartz>

    <!-- 
    This configuration is a way to have jobs defined in xml, but will get them written to the database.
    See https://stackoverflow.com/questions/21589964/ramjobstore-quartz-jobs-xml-to-adojobstore-data-move/ 
    -->


    <add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
    <add key="quartz.plugin.xml.fileNames" value="~/Quartz_Jobs_001.xml" />
    <!-- 
    <add key="quartz.plugin.xml.ScanInterval" value="10" />
    -->

    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"/>
    <add key="quartz.jobStore.dataSource" value="default"/>
    <add key="quartz.dataSource.default.connectionString" value="Server=MyServer\MyInstance;Database=QuartzDB;Trusted_Connection=True;Application Name='quartz_config';"/>
    <add key="quartz.dataSource.default.provider" value="SqlServer-20"/>

</quartz>

Which (as you see in the comments in the xml), I got help with.

Here is the original : RAMJobStore (quartz_jobs.xml) to AdoJobStore Data Move



来源:https://stackoverflow.com/questions/24321042/how-to-add-job-with-trigger-for-running-quartz-net-scheduler-instance-without-re

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!