UseRemoteRun

Configures the scheduler to offload synchronous run execution to a remote HTTP endpoint instead of executing in-process. The call blocks until the remote train completes and returns the output.

Signature

public SchedulerConfigurationBuilder UseRemoteRun(
    Action<RemoteRunOptions> configure
)

Parameters

ParameterTypeRequiredDescription
configureAction<RemoteRunOptions>YesCallback to set the remote endpoint URL and HTTP client options

Returns

SchedulerConfigurationBuilder — for continued fluent chaining.

RemoteRunOptions

PropertyTypeDefaultDescription
BaseUrlstring(required)The URL of the remote endpoint that receives run requests (e.g., https://my-runner.example.com/trax/run)
ConfigureHttpClientAction<HttpClient>?nullOptional callback to configure the HttpClient — add auth headers, custom timeouts, or any other HTTP configuration
TimeoutTimeSpan5 minutesHTTP request timeout. Longer default than UseRemoteWorkers (30s) because run requests block until the train completes
RetryHttpRetryOptions(see below)Retry options for transient HTTP failures (429, 502, 503). Same configuration as RemoteWorkerOptions.Retry

Examples

Basic Usage

services.AddTrax(trax => trax
    .AddEffects(effects => effects
        .UsePostgres(connectionString)
    )
    .AddMediator(assemblies)
    .AddScheduler(scheduler => scheduler
        .UseRemoteWorkers(
            remote => remote.BaseUrl = "https://my-runner.example.com/trax/execute",
            routing => routing.ForTrain<IMyTrain>()
        )
        .UseRemoteRun(remote =>
            remote.BaseUrl = "https://my-runner.example.com/trax/run"
        )
    )
);

With Authentication

.UseRemoteRun(remote =>
{
    remote.BaseUrl = "https://my-runner.example.com/trax/run";
    remote.ConfigureHttpClient = client =>
        client.DefaultRequestHeaders.Add("Authorization", "Bearer my-token");
})

With Custom Timeout

.UseRemoteRun(remote =>
{
    remote.BaseUrl = "https://my-runner.example.com/trax/run";
    remote.Timeout = TimeSpan.FromMinutes(10);
})

Remote Side Setup

The remote process must map the run endpoint with UseTraxRunEndpoint():

var builder = WebApplication.CreateBuilder(args);
 
builder.Services.AddTrax(trax => trax
    .AddEffects(effects => effects
        .UsePostgres(connectionString)
    )
    .AddMediator(typeof(MyTrain).Assembly)
);
 
var app = builder.Build();
app.UseTraxRunEndpoint("/trax/run");
app.Run();

If the remote also handles queued jobs, add both endpoints:

builder.Services.AddTraxJobRunner();
 
var app = builder.Build();
app.UseTraxJobRunner("/trax/execute");  // queue path
app.UseTraxRunEndpoint("/trax/run");    // synchronous run path
app.Run();

Registered Services

UseRemoteRun() registers:

ServiceLifetimeDescription
RemoteRunOptionsSingletonConfiguration options
IRunExecutor -> HttpRunExecutorScopedDispatches run requests via HTTP POST, blocks until response

> Note: Without UseRemoteRun(), the default LocalRunExecutor executes trains in-process via ITrainBus.RunAsync(). UseRemoteRun() overrides this via last-registration-wins.

How It Works

When a GraphQL run* mutation is called, the HttpRunExecutor:

  1. Serializes a RemoteRunRequest containing the train name, input JSON, and input type
  2. POSTs the JSON payload to BaseUrl
  3. Blocks until the remote endpoint returns a RemoteRunResponse
  4. On success: deserializes the train output from the response and returns it to GraphQL
  5. On error: throws a TrainException with the remote error message

The remote endpoint (UseTraxRunEndpoint) calls ITrainExecutionService.RunAsync() locally — which creates metadata, runs the train, and returns the output. Since both processes share the same Postgres database, the metadata is visible to the dashboard.

Differences from UseRemoteWorkers

UseRemoteRunUseRemoteWorkers
Execution pathrun* mutationsqueue* mutations
BlockingYes — blocks until train completesNo — returns immediately with WorkQueueId
ReturnsTrain output (deserialized from response)WorkQueueId + ExternalId
Remote endpointUseTraxRunEndpoint() (/trax/run)UseTraxJobRunner() (/trax/execute)
AbstractionIRunExecutorIJobSubmitter
Default timeout5 minutes30 seconds

Package

dotnet add package Trax.Scheduler

See Also