ConfigureLocalWorkers

Customizes the built-in PostgreSQL local worker pool. Local workers are registered automatically when UsePostgres() is configured — no explicit call is needed to enable them.

Signature

public SchedulerConfigurationBuilder ConfigureLocalWorkers(
    Action<LocalWorkerOptions> configure
)

Parameters

ParameterTypeRequiredDescription
configureAction<LocalWorkerOptions>YesCallback to customize worker count, polling interval, and timeouts

Returns

SchedulerConfigurationBuilder — for continued fluent chaining.

LocalWorkerOptions

PropertyTypeDefaultDescription
WorkerCountintEnvironment.ProcessorCountNumber of concurrent worker tasks polling for jobs
PollingIntervalTimeSpan1 secondHow often idle workers poll for new jobs
VisibilityTimeoutTimeSpan30 minutesHow long a claimed job stays invisible before another worker can reclaim it (crash recovery)
BatchSizeint1Number of jobs each worker claims per poll cycle
ShutdownTimeoutTimeSpan30 secondsGrace period for in-flight jobs during shutdown

Examples

Default Behavior (No Call Needed)

When UsePostgres() is configured, local workers are enabled automatically with default settings. You don't need to call anything to get local execution:

services.AddTrax(trax => trax
    .AddEffects(effects => effects
        .UsePostgres(connectionString)
    )
    .AddMediator(typeof(Program).Assembly)
    .AddScheduler(scheduler => scheduler
        .Schedule<IMyTrain, MyInput>("my-job", new MyInput(), Every.Minutes(5))
    )
);

Custom Configuration

Use ConfigureLocalWorkers() to customize worker behavior:

services.AddTrax(trax => trax
    .AddEffects(effects => effects
        .UsePostgres(connectionString)
    )
    .AddMediator(typeof(Program).Assembly)
    .AddScheduler(scheduler => scheduler
        .ConfigureLocalWorkers(options =>
        {
            options.WorkerCount = 4;
            options.PollingInterval = TimeSpan.FromSeconds(2);
            options.VisibilityTimeout = TimeSpan.FromMinutes(15);
            options.ShutdownTimeout = TimeSpan.FromMinutes(1);
        })
        .Schedule<IMyTrain, MyInput>("my-job", new MyInput(), Every.Minutes(5))
    )
);

Mixed Local and Remote Workers

Local workers are always registered alongside remote submitters. Trains not routed to a remote submitter execute locally:

services.AddTrax(trax => trax
    .AddEffects(effects => effects
        .UsePostgres(connectionString)
    )
    .AddMediator(assemblies)
    .AddScheduler(scheduler => scheduler
        .ConfigureLocalWorkers(opts => opts.WorkerCount = 8)
        .UseRemoteWorkers(
            remote => remote.BaseUrl = "https://gpu-workers/trax/execute",
            routing => routing
                .ForTrain<IHeavyComputeTrain>()
                .ForTrain<IAiInferenceTrain>())
        .Schedule<IMyTrain, MyInput>("my-job", new MyInput(), Every.Minutes(5))
        .Schedule<IHeavyComputeTrain, HeavyInput>("heavy-compute", new HeavyInput(), Every.Hours(1))
    )
);

In this example, IHeavyComputeTrain is dispatched to the remote HTTP endpoint, while IMyTrain executes locally with 8 worker threads.

Remarks

  • Local workers are the implicit default when UsePostgres() is configured. You only need ConfigureLocalWorkers() if you want to change the defaults.
  • No connection string parameter is needed. Local workers use the same IDataContext registered by UsePostgres().
  • No additional NuGet packages required — this is included in Trax.Scheduler.
  • Jobs are queued to the trax.background_job table and dequeued atomically using PostgreSQL's FOR UPDATE SKIP LOCKED.
  • Workers delete job rows after execution (both success and failure). Trax.Core's Metadata and DeadLetter tables handle the audit trail.
  • If a worker crashes mid-execution, the job's fetched_at timestamp becomes stale and the job is reclaimed after VisibilityTimeout.
  • When UseRemoteWorkers() or UseSqsWorkers() is also configured, local workers still run — only the trains explicitly routed via ForTrain<T>() or [TraxRemote] are dispatched remotely.

Registered Services

The scheduler automatically registers these services when UsePostgres() is configured:

ServiceLifetimeDescription
LocalWorkerOptionsSingletonConfiguration options
IJobRunnerTrainJobRunnerTrainScopedThe train that workers use to execute each job
IJobSubmitterPostgresJobSubmitterScopedEnqueue implementation (INSERT into background_job)
LocalWorkerServiceHosted ServiceBackground worker that polls and executes jobs

Package

dotnet add package Trax.Scheduler

See Also