IServiceCollection Services { get; }
Source
Gets the application service collection under configuration.
PostgreSQL implementation of the durable Schedule client.
This client persists Schedule command, generation, and occurrence facts but does not start a hosted loop. Use PostgreSqlDurableScheduleProcessor
to run one bounded, manually invoked due pass. The initial implementation admits Work targets only because it can atomically compose the existing caller-owned Work writer. Callers must authorize the Schedule scope before invoking this client. Configure distinct non-owner, non- BYPASSRLS
dispatcher and runtime login roles with the documented PostgreSQL role recipe
, and apply schema version 4 before accepting Schedule work. Hosted activation is intentionally deferred; this client and processor never register or start a background loop.
Continues PostgreSQL durable registration while keeping storage and continuous activation separate.
AppSurfaceDurablePostgreSqlBuilder AddWorkerHost()
Adds the single critical host adapter that continuously invokes the bounded runtime pump.
Use this only in a continuously live worker process. Query-only hosts, migration tools, tests, and scale-to-zero deployments keep storage registration passive and may invoke IDurableRuntimePump
from their own activator instead.
IServiceCollection Services { get; }
Source
Gets the application service collection under configuration.
Controls the PostgreSQL Schedule processor's runtime-role and temporal safety fences.
The role name is checked with current_user
before a Schedule processor sets its scoped RLS setting or bridges an occurrence to Work. The safety window limits how far a single database-clock observation may advance an interval cursor; a larger jump suspends rather than consumes future occurrences.
string RuntimeRole { get; }
Source
Gets the exact role required before Schedule bridge scope is set.
TimeSpan MaximumClockAdvance { get; }
Source
Gets the maximum safe single-pass database-clock advance beyond a stored cursor.
TimeSpan LeaseDuration { get; }
Source
Gets the dispatcher-owned Schedule discovery lease duration, capped at ten minutes.
Reports an explicit compare-and-swap recovery-epoch rotation.
PreviousEpoch
ActiveEpoch
RotatedAtUtc
Carries one private pump outcome, including the original exception required by the legacy projection.
PostgreSqlDurablePumpOutcome Completed(DurableRuntimePumpResult result)
Creates a completed outcome with the exact provider result.
PostgreSqlDurablePumpOutcome Refused(PostgreSqlDurablePumpRefusal refusal, ExceptionDispatchInfo? legacyException = null)
Creates a typed refusal, optionally retaining the exact legacy exception.
PostgreSqlDurablePumpOutcome Incompatible(string problemCode, ExceptionDispatchInfo legacyException)
Creates an incompatible result while retaining the exact legacy exception.
Associates an original pump exception with the phase that produced it.
void Mark(Exception exception, PostgreSqlDurablePumpPhase phase)
Marks an exception without changing its type, message, token, inner exception, or stack.
bool IsFinalizationFailure(Exception exception)
Gets whether terminal finalization, rather than the active pass token, produced this failure.
bool IsExecutionFailure(Exception exception)
Gets whether the sole application execution boundary produced this failure.
Marks a store-admission failure that may have occurred after PostgreSQL accepted the pass-active mutation.
void MarkIndeterminate(Exception exception)
Marks the original exception without wrapping it or changing its legacy projection.
bool TakeIndeterminate(Exception exception)
Consumes whether ownership-scoped cleanup is required before this attempt projects the failure.
Host lifecycle adapter that schedules the one authoritative bounded PostgreSQL runtime pump.
This service is registered only by explicit worker-host composition. It does not apply schema migrations and does not own durable correctness: the store still owns claims, leases, permits, fencing, and durable history.
TimeSpan CalculatePassShutdownWindow()
Calculates the execution window left after finalization and cleanup reserves are protected.
bool HasProviderDeadlineEvidence(Exception exception)
Reports whether package-owned evidence proves that the provider command deadline elapsed.
Runs one bounded, manually invoked PostgreSQL Schedule due pass.
The processor first claims a payload-free dispatch lease through the dispatcher data source, then opens a separate scoped runtime transaction to record and bridge Schedule facts. It does not start a loop, execute Work, invoke a provider, or start Flow targets. Cancellation is observed before each additional lease; work already committed by a prior claim remains durable.
ValueTask<PostgreSqlDurableScheduleProcessResult> ProcessDueAsync(PostgreSqlDurableScheduleProcessRequest request, CancellationToken cancellationToken = default)
Claims and processes up to the requested number of eligible Schedule dispatch rows.
request
cancellationToken
Counts of claimed Schedule rows and resulting durable facts. An empty pass returns zero counts.
Implements low-cardinality PostgreSQL runtime liveness, drain, and worker-generation fencing.
ValueTask<bool> TryBeginPassAsync(CancellationToken cancellationToken)
Preserves the legacy Boolean/exception admission behavior for internal callers and compatibility tests.
ValueTask<PostgreSqlDurableStoreAdmission> TryBeginPassWithOutcomeAsync(CancellationToken cancellationToken)
Attempts store admission and returns typed pre-execution causes without parsing legacy exception messages.
ValueTask<bool> EnsureSessionAsync(NpgsqlConnection connection, NpgsqlTransaction transaction, CancellationToken cancellationToken, bool captureAdmissionOutcome = false)
Creates or verifies this process generation while holding the worker row lock.
Whether the verified generation is currently draining.
ValueTask<RuntimeObservation> ReadObservationAsync(CancellationToken cancellationToken)
Reads metadata, the optional worker generation, and due facts from one statement snapshot and one result row.
ValueTask<RuntimeObservation> ReadObservationAsync(NpgsqlConnection connection, CancellationToken cancellationToken)
Reads the one-row runtime observation through an existing compatible status connection.
RuntimeObservation ReadObservationRow(NpgsqlDataReader reader)
Validates the complete one-row provider result before any public snapshot is constructed.
ValueTask<DateTimeOffset> ReadDatabaseTimestampAsync(CancellationToken cancellationToken)
Reads authoritative database time for a schema-only incompatibility assessment.
ValueTask<DateTimeOffset> ReadDatabaseTimestampAsync(NpgsqlConnection connection, CancellationToken cancellationToken)
Reads authoritative database time through an existing compatible status connection.
Carries a typed store-admission result and the exact legacy exception when one is required.
PostgreSqlDurableStoreAdmission Refused(PostgreSqlDurableStoreAdmissionKind kind)
Creates a refusal that has no legacy exception.
PostgreSqlDurableStoreAdmission WithLegacyException(PostgreSqlDurableStoreAdmissionKind kind, InvalidOperationException legacyException)
Creates a typed outcome that retains the original legacy exception.
PostgreSqlDurableStoreAdmission Admitted { get; }
Source
Gets an admitted result.
Internal signal that lets admission retain the exact plain legacy epoch exception.
InvalidOperationException LegacyException { get; }
Source
Gets the unmodified exception used by the legacy projection.
Internal signal that lets admission retain the exact plain legacy worker-generation exception.
InvalidOperationException LegacyException { get; }
Source
Gets the unmodified exception used by the legacy projection.
Holds canonical, value-free diagnostic destinations shared by PostgreSQL runtime components.
Reports the allowlisted interpretation of one PostgreSQL control-plane failure.
PostgreSqlDurableFailureClassification Propagate { get; }
Source
Gets the propagate-by-default classification.
Executes already-configured Npgsql commands with a cancellation sidecar derived from their inherited timeout.
The helper does not assign NpgsqlCommand.CommandTimeout
or alter connection settings. It records typed deadline evidence against the original exception before any boundary-specific translation. Non-query cancellation caused only by that package deadline becomes TimeoutException
; caller cancellation and every other failure preserve their concrete type, token, SQLSTATE, and stack. The helper is used only for schema status, health observation, and pre-execution runtime admission.
ValueTask<int> ExecuteNonQueryAsync(NpgsqlCommand command, CancellationToken cancellationToken)
Executes a non-query control-plane command.
ValueTask<int> ExecuteNonQueryAsync(NpgsqlCommand command, CancellationToken cancellationToken, Func<CancellationToken, Task<int>> operation)
Executes a non-query control-plane operation and maps only package-owned deadline cancellation.
command
cancellationToken
operation
The number of rows affected by the operation.
TimeoutException
OperationCanceledException
ValueTask<object?> ExecuteScalarAsync(NpgsqlCommand command, CancellationToken cancellationToken)
Executes a scalar control-plane command.
ValueTask<TResult> ExecuteReaderAsync<TResult>(NpgsqlCommand command, Func<NpgsqlDataReader, CancellationToken, ValueTask<TResult>> projector, CancellationToken cancellationToken)
Executes and completely projects a control-plane reader while its deadline remains active.
PostgreSqlDurableTimeoutEvidence GetTimeoutEvidence(Exception exception)
Gets deadline evidence recorded for the original exception.
void RecordTimeoutEvidence(Exception exception, PostgreSqlDurableTimeoutEvidence evidence)
Records package-owned deadline evidence while retaining the original exception object.
ValueTask<TResult> ExecuteOperationAsync<TResult>(NpgsqlCommand command, CancellationToken cancellationToken, Func<CancellationToken, Task<TResult>> operation)
Executes one control-plane operation through the inherited command-timeout sidecar.
This internal seam lets tests exercise cancellation precedence without depending on provider timer races. Production callers use the command-shaped helpers above.
Classifies only explicit, pre-execution PostgreSQL control-plane evidence.
PostgreSqlDurableFailureClassification Classify(PostgreSqlDurableControlPlaneOperation operation, Exception exception, CancellationToken callerCancellationToken)
Returns an allowlisted unavailable or incompatible classification, otherwise the propagate result.
string ProblemForSchema(DurableRuntimeSchemaCompatibility compatibility)
Maps a schema compatibility value to its stable public problem code.
Accepts durable Work through the caller's exact active PostgreSQL transaction.
The writer never opens, commits, rolls back, replaces, or disposes the supplied transaction. Domain state and Work acceptance therefore commit or roll back together in the same database.
ValueTask<DurableOperationResult<DurableWorkAcceptance>> EnqueueAsync(NpgsqlTransaction transaction, DurableWorkRequest request, CancellationToken cancellationToken = default)
Writes one durable acceptance without taking ownership of the transaction.
transaction
request
cancellationToken
The stable new or duplicate acceptance, or an actionable domain problem.
ArgumentNullException
transaction
or request
is null.InvalidOperationException
DurableRuntimeSchemaException
Exception.InnerException
retains that original failure.NpgsqlException
An immutable, provider-owned snapshot of the Work contracts that a host may discover.
This selection is created while the runtime pump is resolved. It intentionally never rereads a custom registry, so later registry mutation cannot widen a running host's discovery authority.
void AddDiscoveryParameters(NpgsqlParameterCollection parameters, int maximumCandidates)
Adds the immutable selection arrays to a Work-discovery command without rebuilding them for every poll.
bool IsEmpty { get; }
Source
Gets whether this host registered no Work contracts.
Callers use this fail-closed gate to avoid invoking discovery with an empty contract array, which PostgreSQL rejects.
Implements explicit package-owned durable schema operations for PostgreSQL.
Migration and epoch mutations hold one session advisory lock across their individual transactions. The session scope is required to prevent another migration owner from interleaving between migrations; lock acquisition is nevertheless bounded and cancellation-aware, and the owning connection is always disposed after the mutation so PostgreSQL releases the lock even when explicit cleanup cannot run.
ValueTask<NpgsqlConnection> OpenStatusConnectionAsync(CancellationToken cancellationToken)
Opens a schema-status connection while preserving the status-acquisition observation seams.
cancellationToken
An open connection owned by the caller.
ValueTask<DurableRuntimeSchemaStatus> GetStatusAsync(NpgsqlConnection connection, CancellationToken cancellationToken)
Reads schema status through an existing connection so a compatible runtime observation can reuse one pool acquisition without changing the migration-fence transaction boundary.
connection
cancellationToken
The installed schema compatibility status.
string GenerateScript(int fromVersion = 0)
The generated script keeps a session-scoped lock because each migration has its own transaction. Lock acquisition is bounded inside a short transaction, and callers must stop on errors and close the session if a migration fails before the final explicit unlock.
ValueTask<DurableRuntimeSchemaApplyResult> ApplyAsync(CancellationToken cancellationToken = default)
Programmatic lock acquisition uses non-blocking polling with a 30-second deadline by default. Cancellation remains distinct from lock contention; a deadline failure is reported as a TimeoutException
with the lock identifier and operator guidance. The lock is released explicitly on every acquired path and by disposing the owning connection as a final safety net.
ValueTask ValidateConnectionAsync(NpgsqlConnection connection, NpgsqlTransaction transaction, CancellationToken cancellationToken)
Validates schema compatibility on the connection and transaction that already hold runtime admission's migration fence.
int RequiredVersion { get; }
Source
Gets the schema version required by this package.
Coordinates process-local pass admission with synchronous shutdown initiation.
bool TryEnter()
Returns whether a new pass may start without acquiring or reserving any separate release handle.
A successful result permits admission only; callers must still serialize active passes independently.
void Close()
Rejects future admissions without waiting for or cancelling an in-flight pass.
void Reopen()
Allows future admissions after a controlled drain rollback or recovery decision.
Implements the preview, evidence-first Flow repair boundary for a scoped PostgreSQL durable runtime.
Applications authorize the trusted scope before this client is invoked. The client never reads a raw Work result into its public assessment and never invokes an executor while applying a repair assertion.
Reports the durable PostgreSQL schema identity, version, epoch, and compatibility.
DurableRuntimeSchemaCompatibility Compatibility { get; }
Source
Gets the compatibility verdict.
Guid StoreId { get; }
Source
Gets the immutable store identity, or empty when unavailable.
Guid? ActiveRuntimeEpoch { get; }
Source
Gets the active recovery epoch, or null before explicit initialization.
int InstalledVersion { get; }
Source
Gets the highest installed migration version.
int RequiredVersion { get; }
Source
Gets the schema version required by this package.
int MinimumReaderVersion { get; }
Source
Gets the oldest runtime protocol allowed to read.
int MaximumReaderVersion { get; }
Source
Gets the newest runtime protocol allowed to read.
int MinimumWriterVersion { get; }
Source
Gets the oldest runtime protocol allowed to write.
int MaximumWriterVersion { get; }
Source
Gets the newest runtime protocol allowed to write.
IReadOnlyList<int> AppliedVersions { get; }
Source
Gets an immutable copy of ordered applied migration versions.
IReadOnlyList<int> PendingVersions { get; }
Source
Gets an immutable copy of ordered pending migration versions.
string? Problem { get; }
Source
Gets the actionable incompatibility explanation, when present.
bool IsCompatible { get; }
Source
Gets whether schema reads and writes may begin.
Provides explicit deployment operations for the AppSurface durable PostgreSQL schema.
Use a migration-owner data source. Runtime registration may validate status but must never apply DDL.
ValueTask<DurableRuntimeSchemaStatus> GetStatusAsync(CancellationToken cancellationToken = default)
Reads installed migration metadata without modifying the database.
cancellationToken
An immutable status snapshot. Missing and incompatible schemas are returned as status, not exceptions.
Npgsql.NpgsqlException
OperationCanceledException
string GenerateScript(int fromVersion = 0)
Generates deterministic SQL for migrations newer than the exact reviewed fromVersion
.
fromVersion
PostgreSqlDurableRuntimeSchemaManager.RequiredVersion
.A migration-owner script that acquires and releases the package advisory lock.
ArgumentOutOfRangeException
fromVersion
is outside the supported range.
The result is forward-only and is not safe to rerun after any selected migration commits. Its advisory-lock acquisition is bounded to 30 seconds by default. If that deadline expires, the generated SQL raises PostgreSQL SQLSTATE 55P03
before migration SQL starts; retry after the active migration owner releases the lock.
ValueTask<DurableRuntimeSchemaApplyResult> ApplyAsync(CancellationToken cancellationToken = default)
Applies pending migrations while holding the package session advisory lock.
cancellationToken
The version range observed before and after application and the ordered versions applied by this call.
DurableRuntimeSchemaException
Npgsql.NpgsqlException
TimeoutException
OperationCanceledException
ValueTask ValidateAsync(CancellationToken cancellationToken = default)
Fails when the installed schema cannot be used without changing it.
cancellationToken
A task that completes when the installed schema is compatible.
DurableRuntimeSchemaException
Npgsql.NpgsqlException
OperationCanceledException
ValueTask<DurableRuntimeEpochActivationResult> InitializeRuntimeEpochAsync(Guid initialEpoch, string actorId, string reasonCode, CancellationToken cancellationToken = default)
Activates the first non-empty store recovery epoch exactly once.
initialEpoch
actorId
-
, _
, .
, or :
.reasonCode
-
, _
, .
, or :
.cancellationToken
The activated epoch and database observation time.
ArgumentException
DurableRuntimeSchemaException
InvalidOperationException
Npgsql.NpgsqlException
TimeoutException
OperationCanceledException
ValueTask<DurableRuntimeEpochRotationResult> RotateRuntimeEpochAsync(Guid expectedActiveEpoch, Guid newActiveEpoch, string actorId, string reasonCode, CancellationToken cancellationToken = default)
Atomically rotates the recovery epoch when the expected epoch remains active.
expectedActiveEpoch
newActiveEpoch
actorId
-
, _
, .
, or :
.reasonCode
-
, _
, .
, or :
.cancellationToken
The previous and active epochs and database observation time.
ArgumentException
DurableRuntimeSchemaException
InvalidOperationException
expectedActiveEpoch
is no longer active.Npgsql.NpgsqlException
TimeoutException
OperationCanceledException
Owns the per-invocation execution seam that later tracing integration instruments.
Slice 6 deliberately makes this a no-op wrapper. Durable Flow trace context, Activities, links, tags, and exports remain #685's responsibility; its narrow integration can replace this implementation without changing claim, permit, completion, or hosted-lifecycle ownership.
ValueTask<DurableEncodedWorkExit> InvokeExitAsync(DurablePreparedWorkInvocation invocation, CancellationToken cancellationToken)
Invokes one prepared provider operation and returns its encoded exit fact.
Forwards cancellation to provider execution and owns no claim, permit, completion, or tracing state.
Internal settings for one-transition Flow processing.
Observes committed protocol barriers used by subprocess crash certification.
Observers run after the named database boundary commits and must preserve that ordering. They must not access the database or initiate another Flow operation, because observers exist only to certify recovery boundaries such as a deterministic subprocess termination.
ValueTask ObserveAsync(string barrier, DurableScopeId scopeId, DurableFlowInstanceId instanceId, long revision, PostgreSqlFlowTelemetryEvidence? traceEvidence, CancellationToken cancellationToken)
Observes a committed Flow protocol barrier.
barrier
scopeId
instanceId
revision
traceEvidence
cancellationToken
A task that completes after the observer records the barrier.
Provides the production barrier observer that preserves ordering without recording a checkpoint.
Describes one payload-free Flow or timer dispatch candidate discovered by the dispatcher role.
DispatchId
ScopeId
Kind
InstanceId
TimerId
PostgreSqlFlowDispatchKind.Timer
candidates.DueAtUtc
ExpectedRevision
Priority
Value-free in-process Activity evidence passed only to deterministic crash-test barriers.
Describes one causal link carried by a crash-test Activity evidence record.
Reports the observable result of processing a single Flow dispatch candidate.
Outcome
ScopeId
InstanceId
State
Revision
ChildWorkId
ProblemCode
Discovers payload-free Flow/timer candidates and commits one replay-safe Flow transition at a time.
Discovery uses only the dispatcher-role data source. Claim and mutation use only the scoped runtime-role source. Evaluation runs after the claim transaction releases every database resource.
Requests one bounded, manually invoked PostgreSQL Schedule processing pass.
This is a passive provider operation. Applications may call it from an external trigger or test, but must not loop it in an ASP.NET request or register hosted work; hosted activation requires the explicit AddWorkerHost()
opt-in.
string LeaseOwner { get; }
Source
Gets the opaque processor identity recorded on a transient dispatch lease.
int MaximumSchedules { get; }
Source
Gets the maximum number of Schedule rows the pass may claim.
Reports the durable facts produced by one bounded Schedule processing pass.
int ClaimedSchedules { get; }
Source
Gets the number of payload-free dispatch rows claimed by this pass.
int RecordedOccurrences { get; }
Source
Gets the number of new or coalesced Schedule occurrence facts recorded.
int MaterializedWorkTargets { get; }
Source
Gets the number of Work target identities materialized by this pass.
int SuspendedSchedules { get; }
Source
Gets the number of Schedules suspended by a safety fence.
Indicates a missing, incompatible, or inconsistent durable PostgreSQL schema.
DurableRuntimeSchemaStatus Status { get; }
Source
Gets the incompatible schema status.
Runs one provider-backed PostgreSQL Pass through Work, Flow, and Schedule Turns.
One pass is deliberately sequential and process-local. PostgreSQL retains all authoritative discovery, claim, lease, permit, completion, schedule, scope, and epoch decisions. The internal execution boundary is intentionally uninstrumented so #685 can attach Activity and ActivityLink behavior without taking ownership of this lifecycle.
ValueTask<PostgreSqlDurablePumpOutcome> RunAttemptAsync(DurableRuntimePumpRequest request, CancellationToken cancellationToken)
Runs the sole private admission and execution state machine shared by both public projections.
PostgreSqlDurablePumpOutcome? ClassifyPreExecutionFailure(PostgreSqlDurableControlPlaneOperation operation, PostgreSqlDurablePumpPhase phase, Exception exception, CancellationToken cancellationToken)
Classifies only a failure that occurred before the execution boundary.
ValueTask TryRecordFailedPassAsync(PostgreSqlDurablePumpPhase originalPhase)
Makes one fresh, bounded ownership-scoped cleanup attempt without replacing the original outcome.
Controls PostgreSQL Work acceptance for one validated store and runtime epoch.
Guid RuntimeEpoch { get; }
Source
Gets the active out-of-band recovery epoch.
Guid ExpectedStoreId { get; }
Source
Gets the expected physical durable store identity.
PostgreSqlDurableWakeNotificationMode WakeNotificationMode { get; }
Source
Gets whether acceptance emits a metadata-only PostgreSQL wake hint.
Reports explicit one-time activation of a store recovery epoch.
ActiveEpoch
ActivatedAtUtc
Accepts durable Work in a short provider-owned PostgreSQL transaction.
Implements the verified, one-Flow retention lifecycle over a scoped PostgreSQL retention-operator connection.
The supplied connection must use the dedicated retention-operator role described by the PostgreSQL role recipe. It is not interchangeable with the runtime or dispatcher data source. The application authorizes every caller, stores archive bytes externally, and decides policy cadence; this client proves only protocol correspondence.
DurableOperationResult<DurableRetentionManifestCreateResult>? MapManifestCreateProcedureOutcome(DurableRetentionManifestCreateRequest request, string outcome)
Maps stable manifest-create procedure rejections before attempting to read a persisted manifest.
Returns null
for successful and duplicate outcomes that require a manifest read.
DurableOperationResult<DurableRetentionMutationResult> MapLifecycleProcedureOutcome(DurableRetentionMutationRequest request, string outcome, string? state, long? sequence)
Maps one stable lifecycle procedure response into the public retention mutation result.
Registers the PostgreSQL durable runtime kernel and its separately opt-in host adapter.
AppSurfaceDurablePostgreSqlBuilder AddAppSurfaceDurablePostgreSql(this IServiceCollection services, NpgsqlDataSource dispatcherDataSource, NpgsqlDataSource runtimeDataSource, PostgreSqlDurableWorkOptions workOptions, PostgreSqlDurableScheduleOptions scheduleOptions, Action<AppSurfaceDurablePostgreSqlOptions>? configure = null)
Registers PostgreSQL durable clients, schema validation, health, drain, and the bounded pump without starting a background worker or applying migrations.
services
dispatcherDataSource
runtimeDataSource
workOptions
configure
callback selects the metadata-only wake-hint policy.scheduleOptions
configure
A builder that can explicitly add continuous host activation.
The supplied data sources must be distinct and configured with roles that are non-owner and free of BYPASSRLS
. The identity check prevents reusing one data source for both roles, but cannot validate the database credentials; see the PostgreSQL role recipe
. This method performs no network I/O or DDL. Apply migrations with a separate migration-owner data source through IDurableRuntimeSchemaManager
before a worker is started.
void ValidatePumpOverrideComposition(IServiceCollection services)
Rejects partial or visibly split opt-in admission overrides before package services are added.
IServiceCollection AddAppSurfaceDurableWorkerHost(this IServiceCollection services)
Adds the one critical continuous worker loop after passive PostgreSQL durable registration.
Calling this method never applies migrations. Startup validates compatibility and the active recovery epoch, then fails closed if either is unsuitable. Repeated calls are idempotent.
IServiceCollection AddAppSurfaceDurablePostgreSqlFlowRetention(this IServiceCollection services, NpgsqlDataSource retentionOperatorDataSource)
Adds the separately authorized verified Flow-retention client after PostgreSQL durable storage registration.
services
retentionOperatorDataSource
The original service collection.
The retention operator is a fourth database role, distinct from migration owner, dispatcher, and runtime. It must not share a data source with either existing service role. This method performs no network I/O or DDL; use the schema manager to apply the explicit retention migration and authorize callers before invoking the client. See the PostgreSQL role recipe
.
Captures the one immutable PostgreSQL durable runtime configuration for a service provider.
DispatcherDataSource
RuntimeDataSource
WorkOptions
ScheduleOptions
Options
InstanceId
Marks that worker-host registration has occurred so repeated composition stays idempotent.
Captures the retention-operator data source for duplicate registration detection.
Builds the canonical V1 descriptor digest for evidence-backed child-effect Flow repair.
The digest binds the persisted suspension shape to the exact activity wait and child Work. Its field order and length-prefixed UTF-8 encoding are a durable compatibility contract: changing either requires a new SchemaId
and a corresponding migration constraint.
string CreateDigest(string suspendedFromState, string code, string source, string workState, Guid waitId, DurableWorkId workId)
Creates the canonical SHA-256 digest of one child-effect suspension descriptor.
suspendedFromState
code
source
workState
waitId
workId
The lowercase hexadecimal SHA-256 descriptor digest.
Describes one ordered, checksum-verified PostgreSQL migration and any client execution override it owns.
Version
Name
Sql
Sha256
Sql
.CommandTimeoutSeconds
null
preserves the configured data-source timeout. Identifies transaction-local trace evidence before it is attached to its committed Flow lineage.
Owns scoped Flow command and query transactions. Processor transactions live in the processing partial.
ValueTask<PostgreSqlDurableFlowTrace?> InsertTraceContextAsync(NpgsqlConnection connection, NpgsqlTransaction transaction, DurableScopeId scopeId, DurableFlowInstanceId instanceId, DurableTraceContext? context, string causeKind, CancellationToken cancellationToken)
Inserts immutable trace evidence into the caller-owned Flow mutation transaction.
The caller must set the scoped runtime context and commit or roll back the supplied transaction. A missing context
produces no row and returns null
. A non-null context must insert exactly one row or the method throws so the enclosing durable mutation cannot commit partial evidence.
ValueTask AttachTraceContextAsync(NpgsqlConnection connection, NpgsqlTransaction transaction, DurableScopeId scopeId, DurableFlowInstanceId instanceId, PostgreSqlDurableFlowTrace? trace, string? commandId, long revision, Guid? waitId, Guid? timerId, DurableWorkId? workId, CancellationToken cancellationToken)
Attaches inserted trace evidence to every Flow record created by the same committed transition.
The caller must use the transaction that inserted trace
. A missing trace is a no-op for an absent context. Otherwise the Flow instance and history pointer, plus every non-null command, wait, timer, or Work pointer, must each update exactly one row; any mismatch throws so the transaction rolls back rather than committing detached causal evidence.
Writes durable Work directly into a caller-owned Npgsql transaction.
Implements application-authorized Work inventory, cancellation, and scope fencing over PostgreSQL.
This is an internal provider implementation of the public Provider SPI. Applications must authorize an operation before calling it; opaque scope and aggregate identities are not authorization grants.
Provides PostgreSQL persistence operations for the durable Work protocol.
This internal class supports controlled derived test seams. Overrides must preserve claim identity, runtime epoch and scope-generation fences, lease ownership, dispatch projection, Work history, and transaction guarantees.
ValueTask<DurableOperationResult<DurableWorkAcceptance>> AcceptFlowChildAsync(NpgsqlTransaction transaction, DurableWorkRequest request, Guid runtimeEpoch, Guid expectedStoreId, bool sendWakeNotification, string derivedActivityId, CancellationToken cancellationToken)
Accepts a Flow child Work with an immutable activity identity while retaining the ordinary Work protocol. The caller owns the surrounding transaction and must register the parent wait before commit.
ValueTask<PostgreSqlDurableWorkClaim?> RenewLeaseAsync(PostgreSqlDurableWorkClaim claim, CancellationToken cancellationToken = default)
Renews the active lease held by a fenced Work claim.
claim
cancellationToken
The renewed claim with its current revision, expiry, and cancellation state, or null
when an epoch, scope, attempt, owner, or lease fence is stale.
Overrides must preserve the current-epoch and active-scope checks, lease and dispatch consistency, durable history semantics, and transactional atomicity of the renewal attempt.
ValueTask ValidateSchemaRemovalForTestingAsync(NpgsqlConnection connection, NpgsqlTransaction transaction, Guid? expectedStoreId, CancellationToken cancellationToken, Func<ValueTask> afterExistence)
Validates schema removal after the successful existence probe without relying on timing.
connection
transaction
expectedStoreId
null
to omit identity validation.cancellationToken
afterExistence
This test-only seam preserves the callback-free production validation contract.
DurableRuntimeSchemaException CreateMissingSchemaException(PostgresException innerException)
Preserves the PostgreSQL failure that exposed a missing schema without copying its server text.
Projects terminal or suspended child Work truth into its retained parent Flow activity wait in the same transaction.
Describes one explicit migration application.
int PreviousVersion { get; }
Source
Gets the version before application.
int CurrentVersion { get; }
Source
Gets the version after application.
IReadOnlyList<int> AppliedVersions { get; }
Source
Gets the versions applied by this operation.
Persists application-authorized durable Flow commands and payload-free queries in PostgreSQL.
This client does not authenticate callers, apply schema migrations, or start a processor. Applications authorize the trusted DurableScopeId
before calling it. The data source must use the scoped runtime role.
ValueTask<DurableOperationResult<DurableFlowCommandResult>> StartAsync(DurableFlowStartRequest request, CancellationToken cancellationToken = default)
Validates context through the selected allowlisted codec. Definition-owned and provider-owned views of the same captured source are compatible. Captured guards are retained if a custom registry selects that source directly; equal metadata from unrelated sources is rejected before storage.
Configures process-local PostgreSQL durable runtime behavior.
These options control activation only. They do not apply migrations, alter durable protocol policy, or replace PostgreSQL leases, recovery epochs, and history as the source of truth. Registering PostgreSQL storage remains passive until AppSurfaceDurablePostgreSqlBuilder.AddWorkerHost
is called.
string WorkerId { get; set; }
Source
Gets or sets the privacy-safe identity written on short-lived claims and runtime heartbeats.
Use a unique value for every concurrently live replica. It is not an authorization credential and must not contain connection details, user input, or other secrets.
bool SendWakeNotifications { get; set; }
Source
Gets or sets whether accepted commands emit metadata-only PostgreSQL wake hints.
Polling remains authoritative when hints are disabled, lost, duplicated, delayed, or unavailable.
int MaximumItemsPerPass { get; set; }
Source
Gets or sets the maximum completed or committed Turns in one hosted pass.
TimeSpan TimeBudgetPerPass { get; set; }
Source
Gets or sets the budget for discovering and starting additional Turns in one hosted pass.
DurableRuntimeSurface HostedSurfaces { get; set; }
Source
Gets or sets the durable surfaces activated by this worker instance.
TimeSpan IdlePollingInterval { get; set; }
Source
Gets or sets the maximum delay between authoritative polling passes when no work is immediately due.
TimeSpan TransientFailureDelay { get; set; }
Source
Gets or sets the bounded delay before retrying a transient store or listener failure.
TimeSpan HeartbeatStaleAfter { get; set; }
Source
Gets or sets how old a heartbeat may become before health reports the worker as stale.
TimeSpan ShutdownReserve { get; set; }
Source
Gets or sets one bounded host-shutdown reserve window for durable finalization or cleanup.
Hosted startup requires TimeBudgetPerPass + (2 * ShutdownReserve) <= HostOptions.ShutdownTimeout
. One fresh reserve protects terminal pass finalization and a second fresh reserve protects ownership-scoped cleanup when finalization fails. An externally activated pass retains its caller-supplied execution budget, then uses the same provider-owned finalization and cleanup reserves.
Declares the host-neutral durable module dependency for applications configuring PostgreSQL explicitly.
This module does not create data sources, choose database credentials, apply migrations, or start a worker. Call AppSurfaceDurablePostgreSqlServiceCollectionExtensions.AddAppSurfaceDurablePostgreSql
with the application's reviewed dispatcher and runtime data sources, then opt into AddWorkerHost
only where continuous activation is intended.
Maintains process-local fair selection order for bounded runtime Turns.
Implements the internal PostgreSQL operator path over the landed provider contracts.
Applications must authorize every request before this client is called.
Centralizes fail-closed conversion between PostgreSQL protocol values and Durable contract enums.
DurableWorkState ParseWorkState(string state)
Projects one persisted Work state or rejects an unknown value as corruption.
string FormatProviderSafety(DurableProviderSafety safety)
Formats one supported provider-safety value for persistence.
DurableProviderSafety ParseProviderSafety(string value)
Parses one persisted provider-safety value or rejects corruption.
string FormatClassification(DurableDataClassification classification)
Formats one supported payload classification for persistence.
DurableDataClassification ParseClassification(string value)
Parses one persisted payload classification or rejects corruption.
Requeues a QueueOne Schedule when its materialized Work target reaches terminal truth.
The Work store invokes this projector in the same transaction that commits terminal Work truth. That makes a coalesced occurrence eligible immediately, without relying on the Schedule's normal interval to wake it.
The definition row is locked before its dispatch row is updated. Schedule processing takes the same definition lock, so a terminal Work transition cannot race a pending occurrence from one active generation into a later generation.
ValueTask RequeuePendingOccurrenceAsync(NpgsqlTransaction transaction, DurableScopeId scopeId, DurableWorkId workId, CancellationToken cancellationToken)
Requeues a pending coalesced Schedule occurrence after its Work target becomes terminal.
transaction
scopeId
workId
cancellationToken
Describes whether the installed durable schema can be used by this package.
Identifies the linear phase reached by one PostgreSQL pump attempt.
Identifies the typed pre-execution cause of a refused pump attempt.
Identifies the private outcome projected through the two public pump contracts.
Identifies the authoritative store-admission outcome before application execution.
Identifies the bounded PostgreSQL control-plane operation that observed a failure.
Identifies whether a control-plane failure is safe to return or must propagate.
Identifies package-owned evidence that an inherited provider command deadline elapsed.
Classifies the payload-free dispatch row that initiated Flow processing.
Describes the durable outcome of attempting to process one Flow dispatch candidate.
Controls advisory PostgreSQL wake notifications after Work acceptance.