Skip to content

Commit

Permalink
Expose more configuration options via programmatic APIs (#1263)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Jul 31, 2021
1 parent 95d7391 commit 5c22881
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/Quartz.Examples.AspNetCore/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ public void ConfigureServices(IServiceCollection services)
// handy when part of cluster or you want to otherwise identify multiple schedulers
q.SchedulerId = "Scheduler-Core";
// you can control whether job interruption happens for running jobs when scheduler is shutting down
q.InterruptJobsOnShutdown = true;
// when QuartzHostedServiceOptions.WaitForJobsToComplete = true or scheduler.Shutdown(waitForJobsToComplete: true)
q.InterruptJobsOnShutdownWithWait = true;
// we can change from the default of 1
q.MaxBatchSize = 5;
// we take this from appsettings.json, just show it's possible
// q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@ public interface IServiceCollectionQuartzConfigurator : IPropertyConfigurer, IPr
{
internal IServiceCollection Services { get; }

void UseTypeLoader<T>() where T : ITypeLoadHelper;
void UseSimpleTypeLoader();

/// <inheritdoc cref="SchedulerBuilder.SchedulerId"/>
string SchedulerId { set; }

/// <inheritdoc cref="SchedulerBuilder.SchedulerName"/>
string SchedulerName { set; }

/// <inheritdoc cref="SchedulerBuilder.MisfireThreshold"/>
TimeSpan MisfireThreshold { set; }

/// <inheritdoc cref="SchedulerBuilder.InterruptJobsOnShutdown"/>
bool InterruptJobsOnShutdown { set; }

/// <inheritdoc cref="SchedulerBuilder.InterruptJobsOnShutdownWithWait"/>
bool InterruptJobsOnShutdownWithWait { set; }

/// <inheritdoc cref="SchedulerBuilder.MaxBatchSize"/>
int MaxBatchSize { set; }

/// <inheritdoc cref="SchedulerBuilder.BatchTriggerAcquisitionFireAheadTimeWindow"/>
TimeSpan BatchTriggerAcquisitionFireAheadTimeWindow { set; }

/// <summary>
/// Configure custom job factory.
/// </summary>
Expand All @@ -20,15 +44,13 @@ public interface IServiceCollectionQuartzConfigurator : IPropertyConfigurer, IPr
/// Use <see cref="MicrosoftDependencyInjectionJobFactory"/> to produce Quartz jobs.
/// </summary>
void UseMicrosoftDependencyInjectionJobFactory(Action<JobFactoryOptions>? configure = null);

/// <summary>
/// Use <see cref="UseMicrosoftDependencyInjectionScopedJobFactory"/> to produce Quartz jobs.
/// </summary>
[Obsolete("Jobs are always created with scope, use UseMicrosoftDependencyInjectionJobFactory")]
void UseMicrosoftDependencyInjectionScopedJobFactory(Action<JobFactoryOptions>? configure = null);

void UseTypeLoader<T>() where T : ITypeLoadHelper;
void UseSimpleTypeLoader();
string SchedulerId { set; }
string SchedulerName { set; }
void UseInMemoryStore(Action<SchedulerBuilder.InMemoryStoreOptions>? configure = null);
void UsePersistentStore(Action<SchedulerBuilder.PersistentStoreOptions> configure);
void UseThreadPool<T>(Action<SchedulerBuilder.ThreadPoolOptions>? configure = null) where T : IThreadPool;
Expand All @@ -37,7 +59,6 @@ public interface IServiceCollectionQuartzConfigurator : IPropertyConfigurer, IPr
void UseZeroSizeThreadPool(Action<SchedulerBuilder.ThreadPoolOptions>? configure = null);
void UseDedicatedThreadPool(int maxConcurrency, Action<SchedulerBuilder.ThreadPoolOptions>? configure = null);
void UseDedicatedThreadPool(Action<SchedulerBuilder.ThreadPoolOptions>? configure = null);
TimeSpan MisfireThreshold { set; }

void AddSchedulerListener<T>() where T : class, ISchedulerListener;
void AddJobListener<T>(params IMatcher<JobKey>[] matchers) where T : class, IJobListener;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ public string SchedulerName
set => schedulerBuilder.SchedulerName = value;
}

public bool InterruptJobsOnShutdown
{
set => schedulerBuilder.InterruptJobsOnShutdown = value;
}

public bool InterruptJobsOnShutdownWithWait
{
set => schedulerBuilder.InterruptJobsOnShutdownWithWait = value;
}

public int MaxBatchSize
{
set => schedulerBuilder.MaxBatchSize = value;
}

public TimeSpan BatchTriggerAcquisitionFireAheadTimeWindow
{
set => schedulerBuilder.BatchTriggerAcquisitionFireAheadTimeWindow = value;
}

public void UseInMemoryStore(Action<SchedulerBuilder.InMemoryStoreOptions>? configure = null)
{
schedulerBuilder.UseInMemoryStore(configure);
Expand Down
1 change: 1 addition & 0 deletions src/Quartz.Tests.Unit/SchedulerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ public async Task TestBasicStorageFunctions()
}

[Test]
[Ignore("not suitable way to monitor tasks")]
public async Task TestShutdownWithSleepReturnsAfterAllThreadsAreStopped()
{
int activeThreads = Process.GetCurrentProcess().Threads.Count;
Expand Down
67 changes: 61 additions & 6 deletions src/Quartz/SchedulerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,7 @@ public SchedulerBuilder ProxyToRemoteScheduler(string address)
return this;
}

/// <summary>
/// The time span by which a trigger must have missed its
/// next-fire-time, in order for it to be considered "misfired" and thus
/// have its misfire instruction applied.
/// </summary>
/// <inheritdoc cref="MisfireThreshold"/>
public SchedulerBuilder WithMisfireThreshold(TimeSpan threshold)
{
MisfireThreshold = threshold;
Expand All @@ -251,17 +247,77 @@ public TimeSpan MisfireThreshold
set => SetProperty("quartz.jobStore.misfireThreshold", ((int) value.TotalMilliseconds).ToString());
}

/// <inheritdoc cref="MaxBatchSize"/>
public SchedulerBuilder WithMaxBatchSize(int batchSize)
{
MaxBatchSize = batchSize;
return this;
}

/// <summary>
/// The maximum number of triggers that a scheduler node is allowed to acquire (for firing) at once.
/// Default value is 1.
/// The larger the number, the more efficient firing is (in situations where there are very many triggers needing to be fired all at once) - but at the cost of possible imbalanced load between cluster nodes.
/// </summary>
public int MaxBatchSize
{
set => SetProperty(StdSchedulerFactory.PropertySchedulerMaxBatchSize, value.ToString());
}

/// <inheritdoc cref="BatchTriggerAcquisitionFireAheadTimeWindow"/>
public SchedulerBuilder WithBatchTriggerAcquisitionFireAheadTimeWindow(TimeSpan timeWindow)
{
BatchTriggerAcquisitionFireAheadTimeWindow = timeWindow;
return this;
}

/// <summary>
/// The amount of time that a trigger is allowed to be acquired and fired ahead of its scheduled fire time.
/// Defaults to TimeSpan.Zero.
/// The larger the number, the more likely batch acquisition of triggers to fire will be able to select and fire more than 1 trigger at a time -at the cost of trigger schedule not being honored precisely (triggers may fire this amount early).
/// This may be useful (for performance’s sake) in situations where the scheduler has very large numbers of triggers that need to be fired at or near the same time.
/// </summary>
public TimeSpan BatchTriggerAcquisitionFireAheadTimeWindow
{
set => SetProperty(StdSchedulerFactory.PropertySchedulerBatchTimeWindow, ((int) value.TotalMilliseconds).ToString());
}

/// <inheritdoc cref="InterruptJobsOnShutdown"/>
public SchedulerBuilder WithInterruptJobsOnShutdown(bool interrupt)
{
InterruptJobsOnShutdown = interrupt;
return this;
}

/// <summary>
/// Whether to interrupt (cancel) job execution on shutdown.
/// </summary>
/// <remarks>
/// Job needs to observe <see cref="IJobExecutionContext.CancellationToken"/>.
/// </remarks>
public bool InterruptJobsOnShutdown
{
set => SetProperty(StdSchedulerFactory.PropertySchedulerInterruptJobsOnShutdown, value.ToString());
}

/// <inheritdoc cref="InterruptJobsOnShutdownWithWait"/>
public SchedulerBuilder WithInterruptJobsOnShutdownWithWait(bool interruptWithWait)
{
InterruptJobsOnShutdownWithWait = interruptWithWait;
return this;
}

/// <summary>
/// Whether to interrupt (cancel) job execution on shutdown when wait for jobs to completed has is specified.
/// </summary>
/// <remarks>
/// Job needs to observe <see cref="IJobExecutionContext.CancellationToken"/>.
/// </remarks>
public bool InterruptJobsOnShutdownWithWait
{
set => SetProperty(StdSchedulerFactory.PropertySchedulerInterruptJobsOnShutdownWithWait, value.ToString());
}

public class ThreadPoolOptions : PropertiesHolder
{
protected internal ThreadPoolOptions(PropertiesHolder parent) : base(parent, "quartz.threadPool")
Expand Down Expand Up @@ -299,7 +355,6 @@ public bool UseProperties
set => SetProperty("quartz.jobStore.useProperties", value.ToString().ToLowerInvariant());
}


/// <summary>
/// Gets or sets the database retry interval.
/// </summary>
Expand Down

0 comments on commit 5c22881

Please sign in to comment.