How it works?
The Task Scheduler relies on two technologies internally:
- Quartz.NET for internal triggering of scheduled actions. For its operation, it uses tables created in the
Task Schedulerdatabase. These tables are internal and should never be manipulated directly. - Neos background server methods for running scheduled jobs. This means that the
Task Schedulernever runs scheduled jobs. It communicates with theTask Runnerservice of the concerned cluster to make it run the job.
What happens when a scheduled task is created or activated?
A Quartz.NET trigger is created for the job with the key StartBackgroundServerMethod.
The trigger key takes the ID of the scheduled task to make it easier to track.
What happens when a scheduled task is triggered?
Triggering a scheduled task corresponds to Quartz.NET calling the StartBackgroundServerMethod job.
An execution ID is first created.
If a StartupTimeout is specified, the processing starts by creating a Quartz.NET trigger for the job with the key HandleBackgroundServerMethodStartupTimeout.
The trigger key takes the execution ID with the suffix /StartupTimeout.
This trigger is set to execute when the StartupTimeout expires.
If the StartupTimeout is not specified, the processing starts by creating a Quartz.NET trigger for the job with the key HandleBackgroundServerMethodGlobalTimeout.
The trigger key takes the execution ID with the suffix /GlobalTimeout.
This trigger is set to execute when the Timeout expires.
A record is then created in the executions table with execution ID as the key.
If an execution is still running on the same tenant, the execution is put into Skipped state and processing stops.
A message is finally sent via pub/sub to request the execution of the background server method.
The TimeToLive of this message takes the StartupTimeout or, failing that, the Timeout.
The Task Scheduler cluster then updates the execution state with the messages sent by the Task Runner when executing the background server methods.
What happens when the job with the key HandleBackgroundServerMethodStartupTimeout is triggered?
| Case | Action |
|---|---|
| When the treatment is finished | Nothing happens in this case. |
| When processing is in progress | A Quartz.NET trigger for the job with the key HandleBackgroundServerMethodGlobalTimeout is created to put the execution into the TimeoutExpired state if it does not complete within the timeout period. |
| When treatment has not started | The execution is put in the TimeoutExpired state and a log is added. Due to the asynchronous and distributed operation of scheduled tasks, the execution may be in progress or start later. In this case, the execution will automatically exit the TimeoutExpired state. |
What happens when the job with the key HandleBackgroundServerMethodGlobalTimeout is triggered?
| Case | Action |
|---|---|
| When the treatment is finished | Nothing happens in this case. |
| When processing is not completed or not started | The execution is put in the TimeoutExpired state and a log is added. Due to the asynchronous and distributed operation of scheduled tasks, the execution may be in progress or start later. In this case, the execution will automatically exit the TimeoutExpired state. |
What happens when events notifying the progress of background server methods are received?
The state of the execution is updated and a log line is created.
When the server method is completed (successfully or in error), the following tasks are additionally executed:
- Existing
Quartz.NETtriggers for the execution of typeHandleBackgroundServerMethodStartupTimeoutorHandleBackgroundServerMethodGlobalTimeoutare removed as they are no longer needed. - A
Quartz.NETtrigger is created for the job with the keyPurgeBackgroundServerMethod. The trigger key has the format{TargetClusterName}/{TenantIdentifier}/{ExecutionIdentifier}. This trigger requests purging of traces of background server method execution.
When an event is received while the execution was in the TimeoutExpired state, it means that despite the timeout expiration, the server method is still running. The execution exits the TimeoutExpired state and a Quartz.NET trigger for the job with the key HandleBackgroundServerMethodGlobalTimeout is recreated to put the execution back to the TimeoutExpired state if it is not finished when the Timeout expires again.
Examples
Successful execution without StartupTimeout
sequenceDiagram
autonumber
participant TaskScheduler as TaskScheduler backend
participant QuartzNET as QuartzNET
participant TaskRunner as BusinessCluster task runner
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job StartBackgroundServerMethod
TaskScheduler->>TaskScheduler: Creates a Guid for execution: AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodGlobalTimeout
TaskScheduler->>TaskScheduler: Saves the execution with id AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>TaskScheduler: Publishes event StartBackgroundServerMethod
Note right of TaskScheduler: Identifier: AD3830F8-7F4D-42A7-81D8-35F93C45012D
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Created
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Started
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Succeeded
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: BusinessCluster/T1/AD3830F8-7F4D-42A7-81D8-35F93C45012D, job: PurgeBackgroundServerMethod
TaskScheduler->>QuartzNET: Unschedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodGlobalTimeout
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job PurgeBackgroundServerMethod
TaskScheduler->>TaskScheduler: Calls IBackgroundServerMethodManager.RequestPurgeAsync
end
Successful execution with StartupTimeout when processing completes before the timeout expires
sequenceDiagram
autonumber
participant TaskScheduler as TaskScheduler backend
participant QuartzNET as QuartzNET
participant TaskRunner as BusinessCluster task runner
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job StartBackgroundServerMethod
TaskScheduler->>TaskScheduler: Creates a Guid for execution: AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>TaskScheduler: Saves the execution with id AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>TaskScheduler: Publishes event StartBackgroundServerMethod
Note right of TaskScheduler: Identifier: AD3830F8-7F4D-42A7-81D8-35F93C45012D
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Created
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Started
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Succeeded
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: BusinessCluster/T1/AD3830F8-7F4D-42A7-81D8-35F93C45012D, job: PurgeBackgroundServerMethod
TaskScheduler->>QuartzNET: Unschedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodStartupTimeout
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job PurgeBackgroundServerMethod
TaskScheduler->>TaskScheduler: Calls IBackgroundServerMethodManager.RequestPurgeAsync
end
Successful execution with StartupTimeout when processing starts before the startup timeout expires
sequenceDiagram
autonumber
participant TaskScheduler as TaskScheduler backend
participant QuartzNET as QuartzNET
participant TaskRunner as BusinessCluster task runner
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job StartBackgroundServerMethod
TaskScheduler->>TaskScheduler: Creates a Guid for execution: AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>TaskScheduler: Saves the execution with id AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>TaskScheduler: Publishes event StartBackgroundServerMethod
Note right of TaskScheduler: Identifier: AD3830F8-7F4D-42A7-81D8-35F93C45012D
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Created
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Started
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodGlobalTimeout
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Succeeded
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: BusinessCluster/T1/AD3830F8-7F4D-42A7-81D8-35F93C45012D, job: PurgeBackgroundServerMethod
TaskScheduler->>QuartzNET: Unschedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodGlobalTimeout
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job PurgeBackgroundServerMethod
TaskScheduler->>TaskScheduler: Calls IBackgroundServerMethodManager.RequestPurgeAsync
end
Execution not started before StartupTimeout expires
sequenceDiagram
autonumber
participant TaskScheduler as TaskScheduler backend
participant QuartzNET as QuartzNET
participant TaskRunner as BusinessCluster task runner
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job StartBackgroundServerMethod
TaskScheduler->>TaskScheduler: Creates a Guid for execution: AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>TaskScheduler: Saves the execution with id AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>TaskScheduler: Publishes event StartBackgroundServerMethod
Note right of TaskScheduler: Identifier: AD3830F8-7F4D-42A7-81D8-35F93C45012D
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>TaskScheduler: Sets execution state to TimeoutExpired and adds a log
end
Execution not completed before GlobalTimeout expires
sequenceDiagram
autonumber
participant TaskScheduler as TaskScheduler backend
participant QuartzNET as QuartzNET
participant TaskRunner as BusinessCluster task runner
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job StartBackgroundServerMethod
TaskScheduler->>TaskScheduler: Creates a Guid for execution: AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>TaskScheduler: Saves the execution with id AD3830F8-7F4D-42A7-81D8-35F93C45012D
TaskScheduler->>TaskScheduler: Publishes event StartBackgroundServerMethod
Note right of TaskScheduler: Identifier: AD3830F8-7F4D-42A7-81D8-35F93C45012D
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Created
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
TaskRunner->>TaskRunner: Publishes event BackgroundServerMethodProgress with state Started
rect rgb(240, 240, 240)
TaskScheduler->>TaskScheduler: Event BackgroundServerMethodProgress received
TaskScheduler->>TaskScheduler: Updates the execution state and adds a log
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job HandleBackgroundServerMethodStartupTimeout
TaskScheduler->>QuartzNET: Schedules job
Note right of TaskScheduler: Key: AD3830F8-7F4D-42A7-81D8-35F93C45012D/GlobalTimeout, job: HandleBackgroundServerMethodGlobalTimeout
end
rect rgb(240, 240, 240)
QuartzNET->>TaskScheduler: Triggers job HandleBackgroundServerMethodGlobalTimeout
TaskScheduler->>TaskScheduler: Sets execution state to TimeoutExpired and adds a log
end