Spindle.Hosting 0.2.1

dotnet add package Spindle.Hosting --version 0.2.1
                    
NuGet\Install-Package Spindle.Hosting -Version 0.2.1
                    
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="Spindle.Hosting" Version="0.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Spindle.Hosting" Version="0.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Spindle.Hosting" />
                    
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 Spindle.Hosting --version 0.2.1
                    
#r "nuget: Spindle.Hosting, 0.2.1"
                    
#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 Spindle.Hosting@0.2.1
                    
#: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=Spindle.Hosting&version=0.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Spindle.Hosting&version=0.2.1
                    
Install as a Cake Tool

Spindle.Hosting

Spindle.Hosting wires the local Spindle runtime into the .NET generic host. It gives you a background worker that advances persisted flow instances over time instead of running every flow to completion inside the caller.

This package is for the local MVP runtime. It uses persistence as the source of truth, polls runnable instances, executes local steps, fires due timers, and replays flows after progress is made.

Register Hosting

Register a store, register your flows, then add the worker.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Spindle;
using Spindle.Abstractions.Core;
using Spindle.Hosting;
using Spindle.Persistence;
using Spindle.Persistence.InMemory;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddSingleton<ISpindleStore, InMemorySpindleStore>();

builder.Services.AddSpindleFlow<MyFlow, MyRequest, MyResult>(
    new FlowName("my-flow"));

builder.Services.AddSpindleWorker(options =>
{
    options.PollInterval = TimeSpan.FromMilliseconds(250);
    options.MaxConcurrentFlowInstances = 4;
    options.MaxStepsPerFlowPerTick = 1;
    options.WorkerId = "worker-1";
});

await builder.Build().RunAsync();

AddSpindleWorker registers:

  • RuntimeSpindleRuntime
  • ISpindleRuntime
  • ISpindleRuntimePump
  • SpindleWorkerHostedService

Start Flows From Another Service

Any hosted service, controller, message consumer, or job can inject ISpindleRuntime and schedule a flow.

public sealed class TextConsumerService(
    ISpindleRuntime runtime)
    : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await runtime.StartAsync<TextRequest, TextResult>(
            new FlowName("text-transform"),
            new TextRequest("Hello Durable Workflows"),
            new StartFlowOptions { IdempotencyKey = "text-1" },
            stoppingToken);
    }
}

The caller only creates the instance and performs the first expansion. The hosted Spindle worker later advances the instance by executing ready local steps, firing due timers, and replaying the flow.

Step Handlers

Register step handlers when flow code uses ctx.StepHandler(...).

builder.Services.AddSpindleStepHandler<MyHandler, MyHandlerRequest, MyHandlerResult>(
    new StepHandlerId("my-handler"));

For this MVP, handlers are local process handlers. Queue-only workers and remote handlers are future work.

Options

SpindleHostOptions controls the local worker loop.

Option Default Purpose
PollInterval 250ms Delay when no progress is made.
MaxFlowInstancesPerTick 100 Maximum runnable instances read per worker tick.
MaxStepsPerFlowPerTick 1 Maximum ready local steps executed for one flow advancement.
MaxConcurrentFlowInstances CPU count Maximum flow instances advanced concurrently.
LeaseDuration 30s Local step lease duration.
WorkerId machine-based Worker identity recorded on attempts and leases.

Keeping MaxStepsPerFlowPerTick small is useful for long-running services because one flow cannot drain all ready work in one pump cycle.

Example

Run the hosting example:

dotnet run --project examples/Spindle.Example.Hosting/Spindle.Example.Hosting.csproj

The example has two hosted services:

  • SpindleWorkerHostedService, registered by AddSpindleWorker, which advances durable flow instances.
  • TextConsumerService, which consumes text from a small in-memory inbox and starts one flow per text value.

The flow transforms each string into upper, lower, and camel-case outputs.

Current Limitations

  • The in-memory store is for tests and local examples only.
  • Only local Immediate and LocalWorker step execution is supported.
  • Queue dispatch, RabbitMQ, EF Core, remote flows, dashboards, source generators, and analyzers are not part of this package yet.
  • The worker polls persistence. Future transport-backed wakeups can reduce polling and support distributed queue workers.
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 (1)

Showing the top 1 NuGet packages that depend on Spindle.Hosting:

Package Downloads
Spindle.Testing

Testing utilities for Spindle.Net workflows.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.1 120 8/25/2026
0.2.0 111 8/25/2026
0.1.0 116 8/25/2026
0.1.0-preview.2 73 6/29/2026
0.1.0-preview.1 89 6/29/2026