# TraconSchedulingOptions

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.traconschedulingoptions/
> Summary: TraconSchedulingOptions: Batch and scheduled run settings.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Abstractions.dll</code></div>

Batch and scheduled run settings.

```csharp
public sealed class TraconSchedulingOptions
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.traconschedulingoptions/">TraconSchedulingOptions</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

Read from the `Tracon:Scheduling` configuration section. See
`TraconServiceCollectionExtensions.UseScheduling`.

## Constructors

### <a id="Tracon_TraconSchedulingOptions__ctor"></a> TraconSchedulingOptions\(\)

```csharp
public TraconSchedulingOptions()
```

## Fields

### <a id="Tracon_TraconSchedulingOptions_SectionName"></a> SectionName

The configuration section name.

```csharp
public const string SectionName = "Tracon:Scheduling"
```

#### Field Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

## Properties

### <a id="Tracon_TraconSchedulingOptions_Enabled"></a> Enabled

Whether the scheduling subsystem is enabled.

```csharp
public bool Enabled { get; set; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_TraconSchedulingOptions_HttpSchedulableHandlerKeys"></a> HttpSchedulableHandlerKeys

The handler keys `PUT /api/schedules/{name}` accepts. Empty — the
default — means the built-in keys only ([JobHandlerKeys.BuiltIn](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_BuiltIn)),
except [JobHandlerKeys.WorkflowRun](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_WorkflowRun), which no list can allow.

```csharp
public IList<string> HttpSchedulableHandlerKeys { get; }
```

#### Property Value

 [IList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ilist\-1)<[string](https://learn.microsoft.com/dotnet/api/system.string)\>

#### Remarks

A handler key is a dispatch identity, so an unrestricted schedule
endpoint would turn **every registered handler** — including
internal ones a consumer registered for its own background work — into
an externally callable surface. This list is the opt-in: a consumer that
wants its own key schedulable over HTTP names that key here, explicitly.

A non-empty list **replaces** the built-in default, it
does not extend it. This is deliberate — narrowing the surface (allowing
only [JobHandlerKeys.AgentBatch](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_AgentBatch), say) is a thing an
allow-list has to be able to express. The consequence is that a list
naming only a consumer key turns *every* built-in key off; a
consumer that wants both adds the built-in keys it needs alongside its
own, for example
`[.. JobHandlerKeys.BuiltIn, "contoso.nightly-report"]`.

It restricts only the HTTP schedule endpoint. Code paths inside the
process ([IJobDispatcher](/api/tracon.ijobdispatcher/), the built-in producers) are not
affected, and neither is reading: `GET /api/jobs?handlerKey=`
still returns jobs of any key the caller's tenant owns.

### <a id="Tracon_TraconSchedulingOptions_LaneByHandlerKey"></a> LaneByHandlerKey

Maps a handler key to the lane its jobs are queued under, when the
caller did not set [JobRecord.Lane](/api/tracon.jobrecord/#Tracon_JobRecord_Lane)/[JobSchedule.Lane](/api/tracon.jobschedule/#Tracon_JobSchedule_Lane)
explicitly.

```csharp
public IDictionary<string, string> LaneByHandlerKey { get; }
```

#### Property Value

 [IDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.idictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [string](https://learn.microsoft.com/dotnet/api/system.string)\>

#### Remarks

Applied once, inside [IJobStore.EnqueueAsync](/api/tracon.ijobstore/#Tracon_IJobStore_EnqueueAsync_Tracon_JobRecord_System_Collections_Generic_IReadOnlyList_System_String__System_Threading_CancellationToken_): a job whose
`Lane` is still [JobLanes.Default](/api/tracon.joblanes/#Tracon_JobLanes_Default) at enqueue time is
routed through this map by its [JobRecord.HandlerKey](/api/tracon.jobrecord/#Tracon_JobRecord_HandlerKey). This
lets an operator isolate one kind of work (for example
[JobHandlerKeys.Retention](/api/tracon.jobhandlerkeys/#Tracon_JobHandlerKeys_Retention), or a consumer's own key) into
its own lane without changing any call site that creates those jobs.

### <a id="Tracon_TraconSchedulingOptions_Lanes"></a> Lanes

The lanes this worker leases from. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (the
default) leases from every lane — the same behavior as before lanes
existed.

```csharp
public IReadOnlyList<string>? Lanes { get; set; }
```

#### Property Value

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[string](https://learn.microsoft.com/dotnet/api/system.string)\>?

#### Remarks

A worker that only wants to run a specific lane's jobs in a dedicated
process sets this instead of registering a second
`JobWorkerBackgroundService`: the background service is a single
`TryAddEnumerable` registration keyed by implementation type, so a
second host process with its own [TraconSchedulingOptions.Lanes](/api/tracon.traconschedulingoptions/#Tracon_TraconSchedulingOptions_Lanes) value is the
supported way to dedicate capacity, not a second in-process worker.

### <a id="Tracon_TraconSchedulingOptions_LeaseDuration"></a> LeaseDuration

A job's lease duration. If the worker does not finish within this time, the job may be re-leased.

```csharp
public TimeSpan LeaseDuration { get; set; }
```

#### Property Value

 [TimeSpan](https://learn.microsoft.com/dotnet/api/system.timespan)

### <a id="Tracon_TraconSchedulingOptions_MaxAttempts"></a> MaxAttempts

The maximum number of attempts a job may make before becoming [JobStatus.Failed](/api/tracon.jobstatus/).

```csharp
public int MaxAttempts { get; set; }
```

#### Property Value

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_TraconSchedulingOptions_MaxConcurrentJobs"></a> MaxConcurrentJobs

The maximum number of jobs that may run concurrently in this process.

```csharp
public int MaxConcurrentJobs { get; set; }
```

#### Property Value

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_TraconSchedulingOptions_MaxConcurrentJobsPerLane"></a> MaxConcurrentJobsPerLane

Per-lane concurrency limits. A lane not listed here shares the common
[TraconSchedulingOptions.MaxConcurrentJobs](/api/tracon.traconschedulingoptions/#Tracon_TraconSchedulingOptions_MaxConcurrentJobs) budget.

```csharp
public IDictionary<string, int> MaxConcurrentJobsPerLane { get; }
```

#### Property Value

 [IDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.idictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [int](https://learn.microsoft.com/dotnet/api/system.int32)\>

#### Remarks

The sum of these values is allowed to exceed [TraconSchedulingOptions.MaxConcurrentJobs](/api/tracon.traconschedulingoptions/#Tracon_TraconSchedulingOptions_MaxConcurrentJobs):
each listed lane gets its own dedicated budget, on top of the shared
one that unlisted lanes still draw from. There is no combined cap.

If [TraconSchedulingOptions.Lanes](/api/tracon.traconschedulingoptions/#Tracon_TraconSchedulingOptions_Lanes) is left [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (unrestricted)
while this dictionary is non-empty, the worker's effective coverage
narrows to [JobLanes.Default](/api/tracon.joblanes/#Tracon_JobLanes_Default) plus the lanes listed here —
it does **not** also lease from an arbitrary lane nobody
configured a budget for. This keeps the "which lanes get how much
capacity" question answerable from this dictionary alone; a job queued
under an unlisted, non-default lane simply is not leased by this
worker (it stays visible in `GET /api/jobs?lane=` and the jobs
screen). Set [TraconSchedulingOptions.Lanes](/api/tracon.traconschedulingoptions/#Tracon_TraconSchedulingOptions_Lanes) explicitly to include such a lane.

### <a id="Tracon_TraconSchedulingOptions_MaxDurationByHandlerKey"></a> MaxDurationByHandlerKey

Maps a handler key to the longest time one attempt of its jobs may run, when
the job sets no [JobRecord.MaxDuration](/api/tracon.jobrecord/#Tracon_JobRecord_MaxDuration) of its own. Empty — the
default — means no job has a time limit.

```csharp
public IDictionary<string, TimeSpan> MaxDurationByHandlerKey { get; }
```

#### Property Value

 [IDictionary](https://learn.microsoft.com/dotnet/api/system.collections.generic.idictionary\-2)<[string](https://learn.microsoft.com/dotnet/api/system.string), [TimeSpan](https://learn.microsoft.com/dotnet/api/system.timespan)\>

#### Remarks

The worker reads the map when it leases a job, so it covers every job of the
key: one queued from code, from a schedule, from a trigger, or by another
store. The job's own value wins over the map.

When the time is up the handler's token is cancelled and the attempt fails
with [JobErrorCodes.MaxDurationExceeded](/api/tracon.joberrorcodes/#Tracon_JobErrorCodes_MaxDurationExceeded); see
[JobRecord.MaxDuration](/api/tracon.jobrecord/#Tracon_JobRecord_MaxDuration). The limit is per attempt. A handler that
ignores its token is not stopped: give a handler that calls out to the network
its own timeout as well.

Each value must be from one millisecond to about 49.7 days, and each key a
valid handler key; any other entry fails at startup.

```json
"Tracon": {
  "Scheduling": {
    "MaxDurationByHandlerKey": { "tracon.workflow": "00:30:00" }
  }
}
```

### <a id="Tracon_TraconSchedulingOptions_MaxItemsPerJob"></a> MaxItemsPerJob

The maximum number of items allowed in a single job.

```csharp
public int MaxItemsPerJob { get; set; }
```

#### Property Value

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_TraconSchedulingOptions_PollInterval"></a> PollInterval

How often new jobs and due schedules are looked for.

```csharp
public TimeSpan PollInterval { get; set; }
```

#### Property Value

 [TimeSpan](https://learn.microsoft.com/dotnet/api/system.timespan)

### <a id="Tracon_TraconSchedulingOptions_RunWorker"></a> RunWorker

Whether the background worker runs in this process. If set to
[false](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool), the queue and schedule stores keep working,
but no job is leased or executed in this process — distribution is
left to another process.

```csharp
public bool RunWorker { get; set; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)
