Class ExecutionLimitsBuilder
- Namespace
- Quartz
- Assembly
- Quartz.dll
Builds the ExecutionLimits a scheduler applies when it acquires triggers.
public sealed class ExecutionLimitsBuilder
- Inheritance
-
ExecutionLimitsBuilder
- Inherited Members
Examples
ExecutionLimits limits = ExecutionLimitsBuilder.Create()
.ForGroup("high-cpu", 2) // two on this node
.ForGroup("tenant-acme", 8, ExecutionLimitScope.Cluster) // eight across the cluster
.ForOtherGroups(5)
.Build();
Remarks
The builder is mutable and the ExecutionLimits that Build() returns is not, so a snapshot handed to SetExecutionLimits(ExecutionLimits?, CancellationToken) cannot change underneath the scheduler thread that reads it.
UseExecutionLimits(Action<ExecutionLimitsBuilder>) hands one of these to a callback, which is the usual way to configure limits.
Methods
Build()
Takes an immutable snapshot of what has been configured so far.
public ExecutionLimits Build()
Returns
Create()
Create an ExecutionLimitsBuilder with no limits configured.
public static ExecutionLimitsBuilder Create()
Returns
- ExecutionLimitsBuilder
the new ExecutionLimitsBuilder
ForDefaultGroup(int, ExecutionLimitScope)
Set the concurrency limit for triggers that have no execution group.
public ExecutionLimitsBuilder ForDefaultGroup(int maxConcurrent, ExecutionLimitScope scope = ExecutionLimitScope.Node)
Parameters
maxConcurrentintMaximum concurrent threads (must be >= 0), or
0to forbid execution.scopeExecutionLimitScopeWhether the limit counts what this node runs or what the whole cluster runs.
Returns
- ExecutionLimitsBuilder
This builder for fluent chaining.
Exceptions
- ArgumentOutOfRangeException
maxConcurrentis negative, orscopeis not one of the defined values.
ForGroup(string, int, ExecutionLimitScope)
Set the concurrency limit for a named execution group.
public ExecutionLimitsBuilder ForGroup(string group, int maxConcurrent, ExecutionLimitScope scope = ExecutionLimitScope.Node)
Parameters
groupstringThe execution group name.
maxConcurrentintMaximum concurrent threads (must be >= 0), or
0to forbid execution.scopeExecutionLimitScopeWhether the limit counts what this node runs or what the whole cluster runs. Node-scoped unless said otherwise, which is what execution limits have always meant.
Returns
- ExecutionLimitsBuilder
This builder for fluent chaining.
Exceptions
- ArgumentNullException
groupis null.- ArgumentException
groupis a reserved name.- ArgumentOutOfRangeException
maxConcurrentis negative, orscopeis not one of the defined values.
ForOtherGroups(int, ExecutionLimitScope)
Set the default concurrency limit applied to any execution group not explicitly configured.
public ExecutionLimitsBuilder ForOtherGroups(int maxConcurrent, ExecutionLimitScope scope = ExecutionLimitScope.Node)
Parameters
maxConcurrentintMaximum concurrent threads (must be >= 0), or
0to forbid execution.scopeExecutionLimitScopeWhether the limit counts what this node runs or what the whole cluster runs.
Returns
- ExecutionLimitsBuilder
This builder for fluent chaining.
Remarks
The catch-all hands each unlisted group an allowance of its own rather than one they share, and
that holds whichever scope it is declared in: ForOtherGroups(1, ExecutionLimitScope.Cluster)
lets three unlisted tenants run one job each across the cluster, not one job between them.
Exceptions
- ArgumentOutOfRangeException
maxConcurrentis negative, orscopeis not one of the defined values.
Unlimited(string)
Mark a group as having no concurrency limit (unlimited).
public ExecutionLimitsBuilder Unlimited(string group)
Parameters
groupstringThe execution group name.
Returns
- ExecutionLimitsBuilder
This builder for fluent chaining.
Remarks
This is not the same as leaving the group out: an unlisted group falls back to ForOtherGroups(int, ExecutionLimitScope), while an explicitly unlimited one does not. It takes no scope, because unlimited on one node and unlimited across the cluster are the same permission.
Exceptions
- ArgumentNullException
groupis null.- ArgumentException
groupis a reserved name.
UseTriggerGroupWhenUnset()
Treats a trigger that carries no execution group as belonging to a group named after its own Group, for the purpose of these limits.
public ExecutionLimitsBuilder UseTriggerGroupWhenUnset()
Returns
Remarks
For a schedule that already partitions work by trigger group — a tenant per group, a subsystem per group — this caps each partition without restating every group name as an execution group on every trigger. ForGroup(string, int, ExecutionLimitScope) then names trigger groups, and ForOtherGroups(int, ExecutionLimitScope) caps the ones not named.
The derivation is applied where a limit is evaluated and nowhere else: the trigger still carries
no execution group, and the store still persists none. A trigger that does carry one is limited
by that one. Two consequences worth knowing: ungrouped triggers stop falling under
ForDefaultGroup(int, ExecutionLimitScope) — with this on, nothing is ungrouped — and a trigger whose group
happens to be a name the limits reserve (*, _, null) is left ungrouped
rather than folded into the bucket that name means.