Quartz.NET
Quartz.NET is an open-source job scheduling framework for .NET applications. It allows applications to define jobs and control when they execute through triggers, including immediate, delayed, recurring, and calendar-based schedules.
Quartz.NET keeps its jobs and triggers in a job store. NCache integrates with Quartz.NET by providing an NCache-backed implementation of the Quartz IJobStore interface. Instead of keeping scheduling information only in the application process, the integration persists jobs, triggers, calendars, firing records, paused groups, and scheduler check-in records in NCache.
Multiple Quartz scheduler processes can therefore share the same scheduling state and operate as one clustered scheduler.
Important
This integration uses NCache.OSS.Quartz version 5.3.603, targets .NET 10, and references Quartz.NET version 4.6.2.
How NCache Works with Quartz.NET
NCache integrates with Quartz.NET by providing a distributed implementation of the IJobStore interface through the NCache.OSS.Quartz package. This integration allows Quartz.NET to persist jobs, triggers, calendars, execution records, and scheduler state in NCache, enabling multiple application instances to share scheduling information and operate as a clustered scheduler.
Quartz.NET manages job scheduling and execution, including cron expressions, trigger calculations, worker threads, and listeners. The NCache job store detects misfires, invokes the Quartz trigger's misfire calculation, and persists the updated schedule in NCache. It also manages scheduling data, coordinates trigger acquisition across scheduler instances, and supports automatic recovery when a scheduler instance fails.
Applications continue to use the standard Quartz.NET APIs, and job implementations remain unchanged. No NCache-specific code is required within the Quartz IJob implementation.
How Job Scheduling Works
When an application schedules a job, the following workflow takes place:
- The application creates a Quartz job and trigger and schedules them using
IScheduler. - Quartz.NET calculates the trigger's first fire time and passes the job and trigger to the configured job store.
- The NCache job store persists the scheduling information in NCache.
- Scheduler instances request triggers that are ready to execute.
- One scheduler instance acquires a particular firing under a distributed lock. Other instances cannot acquire that same firing simultaneously.
- Quartz.NET executes the job using a worker thread.
- When the execution completes, its resulting scheduling state is persisted in NCache.
Note
The scheduler instance that creates a job does not need to be the instance that executes it. Participating instances share scheduling state through NCache, subject to execution-group and preferred-node routing.
Supported Scheduling Features
The NCache job store supports Quartz.NET scheduling capabilities, including:
- Simple and cron triggers: Execute jobs once, at intervals, or according to a cron expression.
- Calendar-based and recurrence triggers: Use calendar-interval, daily-time-interval, and recurrence schedules.
- Delayed and recurring jobs: Store future fire times and preserve recurring schedules.
- Misfire handling: Apply a trigger's misfire instruction when its scheduled execution is overdue.
- Continuations: Start a trigger after another trigger completes with a specified outcome.
- Pause and resume: Pause jobs, triggers, or groups, optionally recording a reason.
- Concurrency controls: Support non-concurrent jobs, overlap policies, and execution limits.
- Execution groups: Restrict which groups a scheduler node serves or refuses.
- Recovery: Recover work associated with a failed scheduler instance.
- Progress reporting: Persist progress on firing records for querying through Quartz APIs.
Note
Custom triggers and calendars require suitable Quartz serializers registered on every scheduler node.
Clustered Scheduling
Multiple application instances participate in one logical Quartz scheduler by sharing the same NCache job store.
For every running instance of one scheduler:
- CacheName identifies the same NCache cache.
- SchedulerName uses the same logical scheduler name.
- KeyPrefix uses the same prefix.
- InstanceId uniquely identifies each running process.
Each instance periodically stores a check-in record in NCache. This enables other instances to identify scheduler nodes that are no longer responding.
Note
Scheduler nodes coordinate through NCache without requiring direct communication between nodes.
Failure Recovery
If a scheduler node stops checking in, an active scheduler node can recover its outstanding scheduling state. Acquired triggers that were never fired can become available again. Jobs marked for recovery using Quartz's RequestRecovery() can be scheduled to run again after their original node fails during execution.
Recovery is not instantaneous. A scheduler instance is considered stale when the time since its last check-in exceeds its recorded check-in interval plus ClusterCheckinMisfireThreshold. Recovery is performed during subsequent maintenance passes.
The NCache job store also releases stale trigger acquisitions when their age exceeds StaleAcquiredTriggerThreshold, even if the owning scheduler instance is still active. By default, this threshold is the greater of twice MisfireThreshold and two minutes.
When a scheduler restarts using its previous InstanceId, it can also recover its own incomplete work during startup.
For graceful shutdown, configure the Quartz hosted service with WaitForJobsToComplete = true so running jobs can finish before the host stops.
In This Section
NCache as Quartz.NET Job Store
Install, configure, and use NCache as Quartz.NET's persistent job store.