Table of Contents

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

ExecutionLimits

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

maxConcurrent int

Maximum concurrent threads (must be >= 0), or 0 to forbid execution.

scope ExecutionLimitScope

Whether the limit counts what this node runs or what the whole cluster runs.

Returns

ExecutionLimitsBuilder

This builder for fluent chaining.

Exceptions

ArgumentOutOfRangeException

maxConcurrent is negative, or scope is 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

group string

The execution group name.

maxConcurrent int

Maximum concurrent threads (must be >= 0), or 0 to forbid execution.

scope ExecutionLimitScope

Whether 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

group is null.

ArgumentException

group is a reserved name.

ArgumentOutOfRangeException

maxConcurrent is negative, or scope is 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

maxConcurrent int

Maximum concurrent threads (must be >= 0), or 0 to forbid execution.

scope ExecutionLimitScope

Whether 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

maxConcurrent is negative, or scope is not one of the defined values.

Unlimited(string)

Mark a group as having no concurrency limit (unlimited).

public ExecutionLimitsBuilder Unlimited(string group)

Parameters

group string

The 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

group is null.

ArgumentException

group is 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

ExecutionLimitsBuilder

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.