FluxFlow.Engine.DurableOutput.SqlFile 3.0.0

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package FluxFlow.Engine.DurableOutput.SqlFile --version 3.0.0
                    
NuGet\Install-Package FluxFlow.Engine.DurableOutput.SqlFile -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FluxFlow.Engine.DurableOutput.SqlFile" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FluxFlow.Engine.DurableOutput.SqlFile" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="FluxFlow.Engine.DurableOutput.SqlFile" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FluxFlow.Engine.DurableOutput.SqlFile --version 3.0.0
                    
#r "nuget: FluxFlow.Engine.DurableOutput.SqlFile, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FluxFlow.Engine.DurableOutput.SqlFile@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FluxFlow.Engine.DurableOutput.SqlFile&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=FluxFlow.Engine.DurableOutput.SqlFile&version=3.0.0
                    
Install as a Cake Tool

FluxFlow.Engine.DurableOutput.SqlFile

Production SQLite single-file implementation of IDurableOutputStore, IDurableOutputDeliveryStore, IDurableOutputDeadLetterStore, and IDurableOutputStatusStore, and IDurableOutputRetentionStore for local FluxFlow hosts. One container-owned singleton provides all five aliases.

Use another provider for a shared network database, document store, or distributed deployment. The provider-neutral capture declarations, dispatcher, and operational contracts remain unchanged.

Registration

using FluxFlow.Composition.Addressing;
using FluxFlow.Engine.DurableOutput;
using FluxFlow.Engine.DurableOutput.SqlFile;

services
    .AddFluxFlowSqlFileDurableOutput(store =>
    {
        store.DatabasePath = "data/fluxflow-output.db";
        store.BusyTimeout = TimeSpan.FromSeconds(30);
    })
    .AddFluxFlowDurableOutput(outputs =>
    {
        outputs.Capture(
            ApplicationAddress.WorkflowPort("Orders", "Complete", "Output"),
            "orders.completed.v1",
            ApplicationJsonContext.Default.OrderCompleted);
    })
    .AddSingleton<IDurableOutputDeliveryHandler, OrderDeliveryHandler>()
    .AddFluxFlowDurableOutputDelivery(delivery =>
    {
        delivery.LeaseDuration = TimeSpan.FromMinutes(1);
        delivery.LeaseRenewalInterval = TimeSpan.FromSeconds(20);
        delivery.RetryDelay = TimeSpan.FromSeconds(10);
        delivery.IdleDelay = TimeSpan.FromMilliseconds(500);
        delivery.MaxDeliveryAttempts = 5;
    });

Capture and delivery remain independent. A capture-only host omits the handler and delivery registration. Registration freezes settings but performs no file, connection, schema, or background work. Merely resolving none of the delivery or operational aliases causes no delivery-table I/O.

DatabasePath is required. Relative paths are allowed by default. Set AllowAbsoluteDatabasePath when an absolute path is intentional. CreateDirectory and CreateDatabase default to true.

Persistence

The capture schema owns immutable envelopes and atomic Enqueued, equivalent-content AlreadyExists, or no-overwrite Conflict results for the binary (application_address, message_id) key.

The independent lazy delivery schema is version 2 and contains:

  • fluxflow_durable_output_delivery_schema;
  • fluxflow_durable_output_deliveries;
  • ix_fluxflow_durable_output_deliveries_eligibility;
  • ix_fluxflow_durable_output_deliveries_dead_lettered.

Version-1 delivery databases migrate transactionally. Existing pending, leased, and completed rows retain keys, schedules, lease ownership/tokens, attempts, timestamps, offsets, and completion tombstones. New dead-letter metadata starts empty with generation zero. Capture and co-located durable-input tables are not modified.

Every lease transaction backfills missing pending state from captured outputs, selects at most one due or expired row deterministically, assigns a new token, and increments the attempt. Renewal, completion, retry, and dead-letter settlement require the exact current unexpired token. Renewal changes only the lease-expiry columns and requires no schema migration. Dead-letter settlement stores only HandlerFailure, an exact timestamp, and an incremented generation; it stores no exception text.

Inspection And Replay

Resolve IDurableOutputDeadLetterStore from DI to:

  • list bounded payload-free summaries with exact filters and stable keyset pagination;
  • retrieve one exact complete envelope by key; or
  • replay one current dead letter with an expected generation and explicit next attempt time.

Replay returns the row to pending, resets its attempt to zero, clears failure state, preserves its complete captured envelope and generation, and does not deliver immediately. A stale operator view cannot replay a later dead-letter cycle. Completed tombstones and already replayed rows are never replayed.

SQLite coordinates concurrent instances, enforces one-winner transitions, uses the configured bounded busy timeout, and preserves cancellation before its non-cancelable commit boundary. Store disposal is idempotent and clears its connection pool.

Provider Conformance

The SQL-file test project is the first concrete adapter for the reusable durable-output capture, delivery, and dead-letter conformance suites. Thin provider subclasses create a fresh temporary database and expose the applicable narrow interfaces; the shared tests own backend-independent lease, renewal, settlement, ordering, inspection, replay, and concurrency semantics.

SQLite-specific tests remain separate for the exact schema and indexes, version-1-to-version-2 migration, registration aliases and conflicts, lazy initialization, write-lock/busy-timeout behavior, corrupt rows, persistence and reopen, connection-pool disposal, and durable input/output coexistence. A future provider should follow the same split: pass the shared behavioral floor and add focused tests for the risks of its own backend and deployment model.

Scope

This provider is for local single-file deployment. Delivery is serial and at-least-once; handlers remain responsible for destination idempotency. There is no automatic replay or purge, transport adapter, variable backoff, batching, parallel delivery, multi-destination routing, distributed coordinator, business-state transaction, workflow checkpoint, or exactly-once guarantee.

Version 3.0 follows the breaking core renewal-interface/options change. It adds no delivery schema version or index; existing version-2 databases remain valid.

Read-Only Status

The same singleton implements IDurableOutputStatusStore. It reports captures, unmaterialized records, delivery states, readiness, and lease expiry without selecting envelope content. If the independent delivery table is absent, captures are reported as unmaterialized and inspection leaves that table absent; status never initializes or migrates either schema. Version 2.1 adds this capability without another schema change.

Explicit Terminal Retention

IDurableOutputRetentionStore resolves to the same singleton. A retention call uses the existing lazy delivery-schema lifecycle, selects a deterministic bounded batch of completed or dead-lettered delivery rows, and deletes their capture parents in one immediate transaction. The existing foreign-key cascade removes delivery rows atomically. Capture-only, pending, leased, replayed, and opposite-terminal records are preserved.

Registration and resolution remain I/O-free, and no schema version or index is added. Calling retention can initialize the existing delivery schema; a capture-only host that never calls it remains capture-only. The host owns the exclusive cutoff and schedule. Purging ends the identity's idempotency or dead-letter replay window.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.0.0-rc.1 65 8/9/2026
3.0.0 107 8/3/2026

Breaking with core 3.0: implements exact-token durable-output lease renewal with a direct transactional update and no schema or dependency change.