All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Durable orchestration: mark a job
.Durable()to coordinate multi-step workflows that trigger child runs, suspend while they wait, and replay from recorded history, surviving restarts and crashes. - Replay-safe helpers on
JobContext—RecordAsync,NewGuidAsync,NewGuidV7Async,GetUtcNowAsync,NextInt32Async, andNextDoubleAsync— plusIsDurableandIsReplayingfor deterministic durable handlers. Suspendedrun status for durable runs waiting on children, surfaced across the dashboard timeline and status filters; suspended runs are not claimed by workers and hold no concurrency slot.- Run expiration via
RunOptions.ExpiresAt,BatchRunOptions.ExpiresAt, andSurefireOptions.RunExpirationPeriodto cancel runs that outlive a deadline. - Job source code on the dashboard through
JobDefinition.SourceCode. DurableExecutionSnapshot,DurableRecord,DurableStepRecord,DurableReplayMismatchException,DurableSuspendOutcome,InputPumpArgumentState, andInvalidInputHistoryExceptionfor the durable execution and input-history APIs.
IJobStorenow coordinates durable runs: status transitions key off a lease epoch (RunStatusTransition.ExpectedLeaseEpoch), and run/batch creation records durable steps. NewTrySuspendRunAsync,CreateDurableRecordAsync,LoadExecutionSnapshotAsync, andGetInputPumpStateAsyncmembers support suspension and replay.- The dashboard shows job source code and reports durable suspension, run expiration, and replay/failure counts, alongside further UI improvements.
These affect custom IJobStore implementations only; applications using the built-in stores are unaffected.
- Run status transitions now key off a lease epoch instead of an attempt number.
RunStatusTransition.ExpectedAttempt(int) is replaced byExpectedLeaseEpoch(long), and theRunStatusTransitionfactory methods (PendingToRunning,RunningToSucceeded,RunningToFailed,RunningToPending,ToCanceled) takelong expectedLeaseEpochin place ofint expectedAttempt. IJobStore.TryCancelRunAsyncnow takeslong? expectedLeaseEpochinstead ofint? expectedAttempt.IJobStore.CreateBatchAsyncandIJobStore.TryCreateRunAsyncnow take an optionalDurableStepRecord?parameter.IJobStoregains new required members for durable orchestration:TrySuspendRunAsync,CreateDurableRecordAsync,LoadExecutionSnapshotAsync,GetInputPumpStateAsync, andAppendEventsIfRunNonTerminalAsync.
- Native AOT and trimming support for the core package, storage providers, and dashboard.
- Source generation for trim-safe job registration, lifecycle callbacks,
IJobClientcalls, andBatchItem.Create. RunArgumentsand descriptor-based APIs for pre-serialized arguments and AOT-safe job and callback registration.services.AddSurefireDashboard(configure?)for dashboard services, options, and JSON metadata.
- Reflection-based registration and client APIs remain available, and now report AOT/trim warnings when analyzers are enabled unless Surefire can replace the call with generated code.
- Dashboard setup now registers its JSON metadata through DI and enables ASP.NET Core request delegate generation for AOT builds.
- Cron jobs using the default
Skipmisfire policy now enqueue the next scheduled occurrence while still skipping backlog.
MapSurefireDashboard(prefix, configure)was removed. Configure dashboard options withservices.AddSurefireDashboard(...), then callapp.MapSurefireDashboard(prefix?).BatchItemnow storesRunArguments?instead ofobject?. UseBatchItem.Create(...)for object arguments, or constructBatchItemwith pre-builtRunArguments.
RunOrderDirectionenum andRunFilter.Directionfor ascending or descending ordering onIJobStore.GetRunsAsync.SurefireDashboardOptions.MaxTreeRuns(default50_000) to cap the run tree response, configurable via a newconfigureparameter onMapSurefireDashboard.GET {prefix}/api/runs/{id}/treereturns the full run tree in a single response withTruncatedandTotalCount.
MapSurefireDashboardsignature is now(prefix, configure); callers passing only the prefix are unaffected.- Dashboard trace view shows the whole run tree with live updates.
- Dashboard UI rework
GET {prefix}/api/runs/{id}/traceandGET {prefix}/api/runs/{id}/childrenendpoints (use/tree).- Public response types
RunTraceResponse,RunChildrenResponse, andSiblingsCursorResponse.
First public preview. APIs and storage schemas may still change before 1.0.
AddSurefireandAddJobfor registering jobs as delegates with parameters resolved from DI and run arguments.- Per-job configuration: cron schedules with timezones, retries with backoff and jitter, timeouts, queues, rate limits, max concurrency, priorities, tags, and continuous jobs.
- Misfire policies (
Skip,FireOnce,FireAll) with an optional cap onFireAllcatch-up. IJobClientfor triggering, running, and observing jobs from anywhere, including from inside other jobs.- Streaming with
IAsyncEnumerable<T>for both inputs and outputs, plus batch helpers (RunBatchAsync,StreamBatchAsync). - Lifecycle callbacks (
OnSuccess,OnRetry,OnDeadLetter) per job and globally. - Filter pipeline (
IJobFilter) for cross-cutting behavior at the global or per-job level. - Cascade cancellation across parent and child runs, run expiration via
NotAfter, and deduplication viaDeduplicationId. - Multi-node coordination with claim/retry handling, heartbeats, and stale-node recovery.
- Embedded dashboard with live logs, progress, run history, trace tree, queues, nodes, and a command palette. Includes a REST API at
{prefix}/api/. - Storage providers: in-memory (default), PostgreSQL (with
LISTEN/NOTIFY), SQL Server, SQLite, and Redis (with Pub/Sub). - OpenTelemetry metrics and traces, plus an ASP.NET Core health check.