steinard
10-08-2010, 07:14 AM
Hi!
Sorry for posting this here, but there should be a Quartz theme on these forum pages.
I've used Quartz for a few years now, and I'm very happy with it and it has worked really great. Lately, new features has required me to use Quartz in another way (before I used it together with spring.net configuration triggering static jobs), mainly letting user defined triggers and jobs stored in the database be executed on the server.
While using the configuration approach, most of Quartz was abstracted away, but now I see that I need to know more. I've created my own ScheduleManager which my code interacts with, and while doing this I see that each scheduler is initialized with 10 threads? Why is that?
I also tried to add more then one trigger setup with different JobDetail objects (instances of different types), but this did not work. So in order to get this to work I had to create one StdSchedulerFactory for producing one new scheduler where I add each pair of trigger and job objects. Since I can alter the config properties given to the StdSchedulerFactory I'm able to produce Schedulers with different names, this seems to be the trick to make things work. But reading the documentation, then this does not seem to be neccessary?
Just to give you an insight into the details, here is the most important code parts:
/// <summary>
/// Internal implementation not available for external code.
/// Class is responsible for creation and registeration of schedules for execution within our type system.
/// </summary>
internal class ScheduleManager : IScheduleManager
{
private static readonly ILog log = LogManager.GetLogger(typeof(ScheduleManager));
private int producedQuartzConfigurations;
private const string QUARTZ_SCHEDULER_INSTANCE_NAME_KEY = "quartz.scheduler.instanceName";
private const string QUARTZ_SCHEDULER_INSTANCE_NAME_VALUE = "DefaultQuartzScheduler";
private const string QUARTZ_THREAD_POOL_TYPE_KEY = "quartz.threadPool.type";
private const string QUARTZ_THREAD_POOL_TYPE_VALUE = "Quartz.Simpl.SimpleThreadPool, Quartz";
private const string QUARTZ_THREAD_POOL_THREAD_COUNT_KEY = "quartz.threadPool.threadCount";
private const string QUARTZ_THREAD_POOL_THREAD_COUNT_VALUE = "3";
private const string QUARTZ_THREAD_POOL_THREAD_PRIORITY_KEY = "quartz.threadPool.threadPriority";
private const string QUARTZ_THREAD_POOL_THREAD_PRIORITY_VALUE = "Normal";
private const string QUARTZ_JOB_STORE_TYPE_KEY = "quartz.jobStore.type";
private const string QUARTZ_JOB_STORE_TYPE_VALUE = "Quartz.Simpl.RAMJobStore, Quartz";
private const string QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_KEY = "quartz.jobStore.misfireThreshold";
private const string QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_VALUE = "60000";
/// <summary>
/// Default constructor initializing this class.
/// </summary>
public ScheduleManager() { }
public NameValueCollection CreateQuartsProperties()
{
producedQuartzConfigurations++;
NameValueCollection props = new NameValueCollection
{
{QUARTZ_SCHEDULER_INSTANCE_NAME_KEY, QUARTZ_SCHEDULER_INSTANCE_NAME_VALUE + producedQuartzConfigurations},
{QUARTZ_THREAD_POOL_TYPE_KEY, QUARTZ_THREAD_POOL_TYPE_VALUE},
{QUARTZ_THREAD_POOL_THREAD_COUNT_KEY, QUARTZ_THREAD_POOL_THREAD_COUNT_VALUE},
{QUARTZ_THREAD_POOL_THREAD_PRIORITY_KEY, QUARTZ_THREAD_POOL_THREAD_PRIORITY_VALUE},
{QUARTZ_JOB_STORE_TYPE_KEY, QUARTZ_JOB_STORE_TYPE_VALUE},
{QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_KEY, QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_VALUE}
};
return props;
}
/// <summary>
/// Util method for creating a scheduler together with a trigger and registers the trigger within the scheduler.
/// </summary>
/// <param name="cronTrigger">The trigger to be registered with the scheduler.</param>
/// <returns>The created scheduler with the given trigger.</returns>
public virtual IScheduler GetScheduler(Trigger cronTrigger)
{
NameValueCollection props = CreateQuartsProperties();
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory(props);
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
AddTriggerToScheduler(sched, cronTrigger, false);
return sched;
}
/// <summary>
/// Creates a trigger containing a cron expression for when a job should be executed.
/// </summary>
/// <param name="job">The job object containing information about what should be executed (which method).</param>
/// <param name="triggerName">The name of the trigger to be creates, used for lookups later by the scheduling manager.</param>
/// <param name="cronExpression">The cron expression to be applied to this trigger, decides when the job should be executed.</param>
/// <returns>The created trigger.</returns>
public virtual Trigger GetCronTrigger(JobDetail job, string triggerName, string cronExpression)
{
CronTriggerObject triggerObject = new CronTriggerObject();
triggerObject.Name = triggerName;
triggerObject.JobDetail = job;
triggerObject.CronExpressionString = cronExpression;
triggerObject.AfterPropertiesSet();
return triggerObject;
}
/// <summary>
/// Add the given trigger to the Scheduler, if it doesn't already exist.
/// Overwrites the trigger in any case if "overwriteExistingJobs" is set.
/// </summary>
/// <param name="trigger">the trigger to be added, holds the job and the cron expression for when to be executed by the scheduler.</param>
/// <param name="overwriteExistingJobs">Flag indicating if existing triggers in the scheduler should be overwritten or not.</param>
private void AddTriggerToScheduler(IScheduler scheduler, Trigger trigger, bool overwriteExistingJobs)
{
...
}
}
I hope anyone with Quartz experience may comment on this way of doing it. Should all trigger and job objects (with different class types) be added to the same scheduler? Why doesn't that work? Is there some sample code somewhere demonstrating something like that working? Why is the scheduler initialized with 10 threads? In my scenario, each scheduler will only have one trigger and job object anyway, why should it then be initialized with 10 threads? Hmm, I guess I've summed up all my questions for now, hope anyone finds this interesting.
Cheers,
Steinar.
Sorry for posting this here, but there should be a Quartz theme on these forum pages.
I've used Quartz for a few years now, and I'm very happy with it and it has worked really great. Lately, new features has required me to use Quartz in another way (before I used it together with spring.net configuration triggering static jobs), mainly letting user defined triggers and jobs stored in the database be executed on the server.
While using the configuration approach, most of Quartz was abstracted away, but now I see that I need to know more. I've created my own ScheduleManager which my code interacts with, and while doing this I see that each scheduler is initialized with 10 threads? Why is that?
I also tried to add more then one trigger setup with different JobDetail objects (instances of different types), but this did not work. So in order to get this to work I had to create one StdSchedulerFactory for producing one new scheduler where I add each pair of trigger and job objects. Since I can alter the config properties given to the StdSchedulerFactory I'm able to produce Schedulers with different names, this seems to be the trick to make things work. But reading the documentation, then this does not seem to be neccessary?
Just to give you an insight into the details, here is the most important code parts:
/// <summary>
/// Internal implementation not available for external code.
/// Class is responsible for creation and registeration of schedules for execution within our type system.
/// </summary>
internal class ScheduleManager : IScheduleManager
{
private static readonly ILog log = LogManager.GetLogger(typeof(ScheduleManager));
private int producedQuartzConfigurations;
private const string QUARTZ_SCHEDULER_INSTANCE_NAME_KEY = "quartz.scheduler.instanceName";
private const string QUARTZ_SCHEDULER_INSTANCE_NAME_VALUE = "DefaultQuartzScheduler";
private const string QUARTZ_THREAD_POOL_TYPE_KEY = "quartz.threadPool.type";
private const string QUARTZ_THREAD_POOL_TYPE_VALUE = "Quartz.Simpl.SimpleThreadPool, Quartz";
private const string QUARTZ_THREAD_POOL_THREAD_COUNT_KEY = "quartz.threadPool.threadCount";
private const string QUARTZ_THREAD_POOL_THREAD_COUNT_VALUE = "3";
private const string QUARTZ_THREAD_POOL_THREAD_PRIORITY_KEY = "quartz.threadPool.threadPriority";
private const string QUARTZ_THREAD_POOL_THREAD_PRIORITY_VALUE = "Normal";
private const string QUARTZ_JOB_STORE_TYPE_KEY = "quartz.jobStore.type";
private const string QUARTZ_JOB_STORE_TYPE_VALUE = "Quartz.Simpl.RAMJobStore, Quartz";
private const string QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_KEY = "quartz.jobStore.misfireThreshold";
private const string QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_VALUE = "60000";
/// <summary>
/// Default constructor initializing this class.
/// </summary>
public ScheduleManager() { }
public NameValueCollection CreateQuartsProperties()
{
producedQuartzConfigurations++;
NameValueCollection props = new NameValueCollection
{
{QUARTZ_SCHEDULER_INSTANCE_NAME_KEY, QUARTZ_SCHEDULER_INSTANCE_NAME_VALUE + producedQuartzConfigurations},
{QUARTZ_THREAD_POOL_TYPE_KEY, QUARTZ_THREAD_POOL_TYPE_VALUE},
{QUARTZ_THREAD_POOL_THREAD_COUNT_KEY, QUARTZ_THREAD_POOL_THREAD_COUNT_VALUE},
{QUARTZ_THREAD_POOL_THREAD_PRIORITY_KEY, QUARTZ_THREAD_POOL_THREAD_PRIORITY_VALUE},
{QUARTZ_JOB_STORE_TYPE_KEY, QUARTZ_JOB_STORE_TYPE_VALUE},
{QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_KEY, QUARTZ_JOB_STORE_MISFIRE_THRESHOLD_VALUE}
};
return props;
}
/// <summary>
/// Util method for creating a scheduler together with a trigger and registers the trigger within the scheduler.
/// </summary>
/// <param name="cronTrigger">The trigger to be registered with the scheduler.</param>
/// <returns>The created scheduler with the given trigger.</returns>
public virtual IScheduler GetScheduler(Trigger cronTrigger)
{
NameValueCollection props = CreateQuartsProperties();
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory(props);
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
AddTriggerToScheduler(sched, cronTrigger, false);
return sched;
}
/// <summary>
/// Creates a trigger containing a cron expression for when a job should be executed.
/// </summary>
/// <param name="job">The job object containing information about what should be executed (which method).</param>
/// <param name="triggerName">The name of the trigger to be creates, used for lookups later by the scheduling manager.</param>
/// <param name="cronExpression">The cron expression to be applied to this trigger, decides when the job should be executed.</param>
/// <returns>The created trigger.</returns>
public virtual Trigger GetCronTrigger(JobDetail job, string triggerName, string cronExpression)
{
CronTriggerObject triggerObject = new CronTriggerObject();
triggerObject.Name = triggerName;
triggerObject.JobDetail = job;
triggerObject.CronExpressionString = cronExpression;
triggerObject.AfterPropertiesSet();
return triggerObject;
}
/// <summary>
/// Add the given trigger to the Scheduler, if it doesn't already exist.
/// Overwrites the trigger in any case if "overwriteExistingJobs" is set.
/// </summary>
/// <param name="trigger">the trigger to be added, holds the job and the cron expression for when to be executed by the scheduler.</param>
/// <param name="overwriteExistingJobs">Flag indicating if existing triggers in the scheduler should be overwritten or not.</param>
private void AddTriggerToScheduler(IScheduler scheduler, Trigger trigger, bool overwriteExistingJobs)
{
...
}
}
I hope anyone with Quartz experience may comment on this way of doing it. Should all trigger and job objects (with different class types) be added to the same scheduler? Why doesn't that work? Is there some sample code somewhere demonstrating something like that working? Why is the scheduler initialized with 10 threads? In my scenario, each scheduler will only have one trigger and job object anyway, why should it then be initialized with 10 threads? Hmm, I guess I've summed up all my questions for now, hope anyone finds this interesting.
Cheers,
Steinar.