Cirreum.Coordination 1.2.0

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

Cirreum.Coordination

NuGet Version NuGet Downloads GitHub Release License .NET

Atomic and ephemeral coordination primitives for .NET — single-use claims, fixed-window throttling, and pub/sub signaling over a pluggable backend

Overview

Cirreum.Coordination provides small, focused coordination primitives with a built-in in-memory default and a pluggable backend — the same charter classic coordination services (ZooKeeper, etcd, Consul) bundle as locks, leases, and watch/notify:

  • IReplayGuard — a single-use claim (atomic set-if-absent): the first caller to claim a token wins; replays within the window are rejected. For nonce / replay protection, idempotency keys, and message de-duplication.
  • IRequestThrottle — an atomic fixed-window counter: records a hit against a key and reports whether the caller is still within the limit. For rate limiting.
  • ISignalBroadcaster — an ephemeral publish/subscribe primitive: notifies whichever instances are currently listening on a channel. At-most-once, unbuffered — a live nudge, not a durable message (for that, use Cirreum.Messaging.Distributed).

It depends only on Microsoft.Extensions.DependencyInjection.Abstractions, so it works standalone in any .NET application. Add Cirreum.Coordination.Redis for distributed, multi-instance coordination.

Installation

dotnet add package Cirreum.Coordination

Usage

Choose a backend once, at the application level:

// single-node / development
builder.Services.AddCoordination(c => c.UseInMemory());

// distributed (reference Cirreum.Coordination.Redis)
builder.Services.AddCoordination(c => c.UseRedis());

Consume the primitives wherever you need them:

public sealed class NonceChecker(IReplayGuard replayGuard) {
    public ValueTask<bool> IsFirstUseAsync(string nonce) =>
        replayGuard.TryClaimAsync(nonce, TimeSpan.FromMinutes(2));   // true once, false on replay
}

public sealed class RateLimiter(IRequestThrottle throttle) {
    public async Task<bool> AllowAsync(string clientId) {
        var outcome = await throttle.RecordAsync(clientId, TimeSpan.FromMinutes(1), limit: 100);
        return outcome.Allowed;   // outcome.RetryAfter hints when throttled
    }
}

public sealed class CacheInvalidationSignal(ISignalBroadcaster broadcaster) {
    public ValueTask NotifyAsync(string key) =>
        broadcaster.PublishAsync("cache-invalidated", Encoding.UTF8.GetBytes(key));

    public ValueTask ListenAsync() =>
        broadcaster.SubscribeAsync("cache-invalidated", (payload, _) => {
            var key = Encoding.UTF8.GetString(payload.Span);
            // evict key locally
            return ValueTask.CompletedTask;
        });
}

Pull-and-validate (fail fast on a missing backend)

A component that requires coordination can pull the dependency so a mis-configured host fails fast at startup rather than at the first request:

services.AddCoordination();                       // ensure: registers a fail-closed sentinel if no backend yet
// ...later, once every registration has run:
CoordinationPostureValidator.Validate(services);  // throws if coordination was pulled but no backend chosen

AddCoordination() (ensure) and AddCoordination(c => c.UseX()) (choose) are idempotent and order-independent — the chosen backend always wins, regardless of call order. Until a backend is chosen, the primitives are backed by a fail-closed sentinel that throws rather than silently allow.

Scoping (sharing one backend across applications and environments)

A distributed backend is one flat keyspace: without a scope, two applications (or a Test and a Production deployment of the same application) sharing an instance share replay claims, throttle windows, and signal channels — colliding throttle keys count against each other, and one deployment's signals are delivered to the other. CoordinationScope namespaces all of it:

builder.Services.AddCoordination(c => c
    .UseRedis()
    .WithScope("MyApp", "Production"));   // canonical {app}:{env}, or WithScope("any-opaque-value")

Distributed adapters fold the scope into every key and channel they touch (the in-memory backend ignores it — a process is already its own scope). The scope value is opaque to this package; composition surfaces that know the application's identity (e.g. Cirreum's authentication composition) provide the canonical {ApplicationName}:{EnvironmentName} default automatically when none is registered, and an explicit WithScope(...) always wins.

Contribution Guidelines

  1. Be conservative with new abstractions
    The API surface must remain stable and meaningful.

  2. Limit dependency expansion
    Only add foundational, version-stable dependencies.

  3. Favor additive, non-breaking changes
    Breaking changes ripple through the entire ecosystem.

  4. Include thorough unit tests
    All primitives and patterns should be independently testable.

  5. Document architectural decisions
    Context and reasoning should be clear for future maintainers.

  6. Follow .NET conventions
    Use established patterns from Microsoft.Extensions.* libraries.

Versioning

Cirreum.Coordination follows Semantic Versioning:

  • Major - Breaking API changes
  • Minor - New features, backward compatible
  • Patch - Bug fixes, backward compatible

License

This project is licensed under the MIT License - see the LICENSE file for details.


Cirreum Foundation Framework
Layered simplicity for modern .NET

Product Compatible and additional computed target framework versions.
.NET 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 (3)

Showing the top 3 NuGet packages that depend on Cirreum.Coordination:

Package Downloads
Cirreum.AuthenticationProvider

Authentication track abstractions for the Cirreum framework (three-pillar separation and composition surface). Defines the contracts scheme packages (ApiKey, SignedRequest, SessionTicket) implement: ISchemeSelector + SchemeCategory, CredentialTransport, ISignedRequestAlgorithm + resolver, SessionTicket primitives, [AllowPendingAuth], IAuthenticationBoundaryResolver, IAuthenticationBuilder. Pure abstractions plus a default impl (DefaultAuthenticationBoundaryResolver) that ships with the contracts. Host-agnostic profile enrichment (IUserProfileEnrichmentBuilder, ClaimsUserProfileEnricher) lives in Cirreum.Contracts/Cirreum.Domain, not here.

Cirreum.Authentication.SignedRequest

SignedRequest authentication scheme for the Cirreum framework. Verifies RFC 9421 HTTP Message Signatures (HMAC-SHA256, with a pluggable algorithm resolver) and RFC 9530 Content-Digest for partner / M2M integrations, and signs outbound requests. Ships the authentication handler, ISchemeSelector, the dynamic credential resolver, and the strict-nonce replay posture.

Cirreum.Coordination.Redis

Redis backend for Cirreum.Coordination — distributed, multi-instance atomic and ephemeral coordination. Implements IReplayGuard (atomic SET NX claim for replay / nonce protection), IRequestThrottle (atomic Lua fixed-window counter for rate limiting), and ISignalBroadcaster (Redis pub/sub live signals for cross-instance notification) over an application-provided StackExchange.Redis IConnectionMultiplexer. CoordinationScope namespaces every key and channel per application/environment so multiple deployments can safely share one instance. The adapter is blind to connection configuration — by default it shares the same connection the rest of your app uses, or UseRedis(connectionKey) rides a dedicated keyed connection — and coordinates across every instance sharing the connection.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 464 7/5/2026
1.1.0 101 7/5/2026
1.0.0 429 7/3/2026