AddScheduler

Adds the Trax.Core scheduler subsystem. Registers ITraxScheduler, the background polling service, and all scheduler infrastructure. Provides a SchedulerConfigurationBuilder lambda for configuring global options, execution backends, and startup schedules.

Signature

// With configuration
public static TraxBuilderWithMediator AddScheduler(
    this TraxBuilderWithMediator builder,
    Func<SchedulerConfigurationBuilder, SchedulerConfigurationBuilder> configure
)

// Parameterless defaults
public static TraxBuilderWithMediator AddScheduler(
    this TraxBuilderWithMediator builder
)

AddScheduler is called on TraxBuilderWithMediator (the return type of AddMediator()), which enforces at compile time that effects and the mediator are configured before the scheduler.

The parameterless overload registers the scheduler with default settings, equivalent to AddScheduler(scheduler => scheduler).

Parameters

Parameter Type Required Description
configure Func<SchedulerConfigurationBuilder, SchedulerConfigurationBuilder> No Lambda that receives the scheduler builder and returns it after configuring options, execution backends, and schedules. Omit for defaults.

Returns

TraxBuilderWithMediator, for continued fluent chaining (adding another AddScheduler() call is not typical, but the type allows further configuration).

Example

services.AddTrax(trax => trax
    .AddEffects(effects => effects
        .UsePostgres(connectionString)
    )
    .AddMediator(typeof(Program).Assembly)
    .AddScheduler(scheduler => scheduler
        .ManifestManagerPollingInterval(TimeSpan.FromSeconds(5))
        .JobDispatcherPollingInterval(TimeSpan.FromSeconds(5))
        .MaxActiveJobs(50)
        .DefaultMaxRetries(5)
        .DefaultRetryDelay(TimeSpan.FromMinutes(2))
        .RetryBackoffMultiplier(2.0)
        .MaxRetryDelay(TimeSpan.FromHours(1))
        .DefaultJobTimeout(TimeSpan.FromMinutes(20))
        .DefaultMisfirePolicy(MisfirePolicy.FireOnceNow)
        .DefaultMisfireThreshold(TimeSpan.FromSeconds(60))
        .RecoverStuckJobsOnStartup()
        .DependentPriorityBoost(16)
        .AddMetadataCleanup()
        .Schedule<MyTrain>(
            "my-job",
            new MyInput(),
            Every.Minutes(5),
            options => options
                .Priority(10)
                .Group("my-group"))
    )
);

SchedulerConfigurationBuilder Options

These methods are available on the SchedulerConfigurationBuilder passed to the configure lambda:

Execution Backend

Method Description
ConfigureLocalWorkers Customizes the built-in PostgreSQL local workers (enabled by default with Postgres)
UseRemoteWorkers Routes specific trains to a remote HTTP endpoint for execution
UseSqsWorkers Routes specific trains to an Amazon SQS queue for execution (Trax.Scheduler.Sqs)
UseRemoteRun Offloads synchronous run execution to a remote endpoint (blocks until complete)
OverrideSubmitter(Action<IServiceCollection>) Registers a custom job submitter implementation

Global Options

Method Parameter Default Description
PollingInterval(TimeSpan) interval 5 seconds Shorthand that sets both ManifestManagerPollingInterval and JobDispatcherPollingInterval to the same value
ManifestManagerPollingInterval(TimeSpan) interval 5 seconds How often the ManifestManager evaluates manifests and writes to the work queue
JobDispatcherPollingInterval(TimeSpan) interval 2 seconds How often the JobDispatcher reads from the work queue and dispatches to the job submitter
MaxConcurrentDispatch(int) maxConcurrent 1 Max entries dispatched concurrently per polling cycle. Increase when using UseRemoteWorkers to avoid sequential HTTP blocking. See Parallel Dispatch
MaxDispatchAttempts(int) maxAttempts 5 Max dispatch attempts before permanently failing a work queue entry. When dispatch fails, the entry is requeued for the next cycle. Set to 0 to disable requeuing (fail immediately). See Failure Handling
MaxActiveJobs(int?) maxJobs 10 Max concurrent active jobs (Pending + InProgress) globally. null = unlimited. Per-group limits can also be set from the dashboard on each ManifestGroup
MaxQueuedJobsPerCycle(int?) limit 100 Max queued work queue entries loaded per JobDispatcher cycle. Prevents unbounded memory usage when the queue is large. null = unlimited. Provides headroom beyond MaxActiveJobs for per-group limit skipping
MaxWorkQueueEntriesPerCycle(int?) limit 200 Max work queue entries created per ManifestManager cycle, distributed fairly across manifest groups (limit / numGroups per group, overflow to higher-priority groups). Prevents a single large group from starving smaller groups. null = unlimited
ExcludeFromMaxActiveJobs<TTrain>() (none) (none) Excludes a train type from the MaxActiveJobs count
DefaultMaxRetries(int) maxRetries 3 Retry attempts before dead-lettering
DefaultRetryDelay(TimeSpan) delay 5 minutes Base delay between retries
RetryBackoffMultiplier(double) multiplier 2.0 Exponential backoff multiplier. Set to 1.0 for constant delay
MaxRetryDelay(TimeSpan) maxDelay 1 hour Caps retry delay to prevent unbounded growth
DefaultJobTimeout(TimeSpan) timeout 20 minutes Timeout after which a running job is considered stuck
DefaultMisfirePolicy(MisfirePolicy) policy FireOnceNow Default misfire policy for manifests that don’t specify one
DefaultMisfireThreshold(TimeSpan) threshold 60 seconds Grace period before misfire policies take effect. If a manifest is overdue by less than this, it fires normally
RecoverStuckJobsOnStartup(bool) recover true Whether to auto-recover stuck jobs on startup
StalePendingTimeout(TimeSpan) timeout 20 minutes Timeout after which a Pending job that was never picked up is automatically failed
StaleInProgressTimeout(TimeSpan) timeout 60 minutes Timeout after which an InProgress job that never completed is automatically failed. Acts as a safety net for hard crashes (Lambda kills, OOM) where FinishServiceTrain never runs. Should be longer than DefaultJobTimeout to allow cooperative cancellation to propagate first
PruneOrphanedManifests(bool) prune true Whether to delete manifests from the database that are no longer defined in the startup configuration. Disable if you create manifests dynamically at runtime via ITraxScheduler
DependentPriorityBoost(int) boost 16 Priority boost added to dependent train work queue entries at dispatch time. Range: 0-31. Dependent trains are dispatched before non-dependent ones by default

Startup Schedules

Method Description
Schedule Schedules a single recurring train (seeded on startup)
ScheduleMany Batch-schedules manifests from a collection
Then / ThenMany Schedules dependent trains
AddMetadataCleanup Enables automatic metadata purging

Remarks

  • AddScheduler requires AddEffects() and AddMediator() to be called first. This is enforced at compile time – AddScheduler is only available on TraxBuilderWithMediator, which is the return type of AddMediator().
  • AddScheduler requires a data provider (UsePostgres() or UseInMemory()). If no data provider is configured, AddScheduler throws InvalidOperationException at build time with a helpful error message showing the required configuration.
  • Internal scheduler trains (ManifestManager, InMemoryManifestManager, JobDispatcher, JobRunner, MetadataCleanup) are automatically excluded from MaxActiveJobs.
  • With UseInMemory(), JobDispatcherPollingService and MetadataCleanupPollingService are not registered. The ManifestManagerPollingService runs an InMemoryManifestManagerTrain that dispatches jobs inline via InMemoryJobSubmitter.
  • Manifests declared via Schedule/ScheduleMany are not created immediately. They are seeded on application startup by the SchedulerStartupService.
  • Manifests declared via Schedule/ThenInclude/Include get a ManifestGroup based on their groupId parameter (defaults to externalId). Per-group dispatch controls (MaxActiveJobs, Priority, IsEnabled) are configured from the dashboard.
  • At build time, the scheduler validates that ManifestGroup dependencies form a DAG (no circular dependencies). If a cycle is detected, AddScheduler throws InvalidOperationException with the groups involved. See Dependent Trains: Cycle Detection.

Back to top

Trax - A .NET framework for Railway Oriented Programming with Effects, Scheduling, and more