Skip to main content

Time Estimator

The console progress display and the scheduler's critical-path ordering use estimated module durations. ModularPipelines registers a default provider, so estimates work without any setup: it stores the latest measured duration of each module and sub-module as a small text file under %APPDATA%/ModularPipelines/EstimatedTimes (the user's application-data folder on each platform).

Estimates are best-effort. If the provider cannot read or write its storage (for example a read-only profile, or several pipelines saving at once), the failure is logged, a default estimate of two minutes is used, and the module's outcome is unaffected. The default provider replaces entries atomically, so concurrent pipelines never read a partially written value.

Custom providers​

Replace the default provider to share estimates between machines, or to derive them from another source such as run history:

var builder = Pipeline.CreateBuilder(args);

builder
.AddModule<Module1>()
.AddModule<Module2>();

builder.AddModuleEstimatedTimeProvider<MyEstimatedTimeProvider>();

await builder.RunAsync();

Implement GetModuleEstimatedTimeAsync and SaveModuleTimeAsync. The sub-module members have default implementations (no stored estimates, and saving does nothing); override them when the provider should also estimate sub-modules.

public sealed class MyEstimatedTimeProvider(IMyDurationStore store) : IModuleEstimatedTimeProvider
{
public async Task<TimeSpan> GetModuleEstimatedTimeAsync(
Type moduleType,
CancellationToken cancellationToken = default)
{
return await store.GetAsync(moduleType.FullName!, cancellationToken)
?? TimeSpan.FromMinutes(2);
}

public Task SaveModuleTimeAsync(
Type moduleType,
TimeSpan duration,
CancellationToken cancellationToken = default)
{
return store.SaveAsync(moduleType.FullName!, duration, cancellationToken);
}
}

When run history is enabled, IRunHistoryReader.GetModuleDurationTrendAsync returns recent measured durations for a module, which a custom provider can average instead of keeping its own storage.