Fluens.Web.Discovery 0.7.4

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

Fluens.Web.Discovery

Consul self-registration and a central, blocking-query-refreshed service catalog for Fluens web applications that start on dynamic ports.

The library owns both halves of discovery per ADR-0004:

  • Registration (write) — the application registers itself into Consul after Kestrel binds, using its real post-start address and port, and deregisters on shutdown. A self-healing reconciler re-applies the held registration on an interval (idempotent upsert), surviving Consul auto-deregistration after transient unhealth.
  • Resolution (read) — a single long-polling worker keeps an in-memory IServiceCatalog (the contract lives in Fluens.Web) converged with Consul; the mesh and HTTP clients read the catalog snapshot instead of each issuing their own Consul query. The worker watches both registration topology and health-state transitions, so a peer recovering from critical is picked up within seconds without a topology change.

The library owns the fluens- meta/tag namespace (DiscoveryMeta: fluens-version, fluens-cluster). The hyphen separator is DNS-safe and legal in both Consul meta keys (which reject .) and tags.

Install

dotnet add package Fluens.Web.Discovery

Usage

builder.AddFluens()
    .AddWeb()
    .AddDiscovery(); // reads "Fluens:Web:Discovery"; no-op when Enabled == false

Configuration (appsettings.json):

{
  "Fluens": {
    "Web": {
      "Discovery": {
        "Enabled": true,
        "Url": "http://localhost:8500",
        "AdvertisedHost": null,
        "ClusterId": "cluster-1",
        "Tags": [ "grpc" ],
        "Meta": { "region": "eu-west" },
        "ReregisterIntervalSeconds": 30,
        "HealthCheckPath": "/health",
        "HealthCheckIntervalSeconds": 10,
        "DeregisterCriticalServiceAfterSeconds": 60,
        "CatalogWaitSeconds": 300
      }
    }
  }
}

Options

Option Default Meaning
Enabled true Master flag; false makes AddDiscovery() a no-op.
Url Consul agent base URL. Required when enabled.
AdvertisedHost null Overrides the bound host (wildcard/Docker/NAT/cross-host). When unset the bound address is trusted.
ClusterId null When set, published as the cluster service meta.
Tags [] Extra tags merged with auto tags.
Meta {} Extra meta merged with auto version/cluster (user wins on collision).
ReregisterIntervalSeconds 30 Interval of the idempotent-upsert reconciler.
HealthCheckPath /health HTTP check path used when a health source is configured.
HealthCheckIntervalSeconds 10 Consul check poll interval.
DeregisterCriticalServiceAfterSeconds 60 Consul DeregisterCriticalServiceAfter auto-cleanup.
CatalogWaitSeconds 300 Max wait time (seconds) of each catalog blocking query (>0).

Address normalization

The advertised address is computed once from IServerAddressesFeature and held. Wildcard/loopback bind tokens ([::], [::1], *, 0.0.0.0) are normalized to localhost. Set AdvertisedHost to advertise a routable host instead of the bound one.

Health check

A health check is registered only when a source is configured, with precedence:

  1. an explicit health path passed to the registration call,
  2. else IHealthEndpointInfo resolved from DI (e.g. provided by Fluens.Web.Healthchecks),
  3. else none.

When present it is a Consul HTTP check with DeregisterCriticalServiceAfter as the native auto-cleanup.

Resolution

AddDiscovery() registers a singleton IServiceCatalog (ServiceCatalog) and a CatalogRefreshWorker. The worker runs two concurrent Consul blocking queriesCatalog.Services (registration topology) and Health.State(HealthStatus.Any) (health transitions), each on its own WaitIndex and bounded by CatalogWaitSeconds — and rebuilds the snapshot as soon as either advances. It then reads the current topology plus per-service Health.Service(passingOnly), assembles an immutable snapshot, and swaps it into the catalog. Reacting to the health index means a peer's critical→passing transition wakes a refresh within seconds even when no service was added or removed. Consumers read the catalog directly:

// Resolve a single healthy endpoint (round-robins across instances).
ResolvedServiceEndpoint? endpoint = catalog.Resolve("orders.eu");

// Enumerate services by tag (and optional meta) — e.g. discover mesh peers.
IReadOnlyList<DiscoveredService> peers = catalog.List(
    "fluens-mesh",
    new Dictionary<string, string> { ["fluens-cluster"] = "cluster-1" });

// React to topology changes.
IChangeToken token = catalog.GetChangeToken();

Sibling libraries that require the catalog (for example the messaging mesh) call the idempotent TryAddDiscovery() — it wires discovery exactly once, so the catalog worker is never registered twice.

ADR-0007 — endpoint resolution only. The catalog answers where to deliver now; it is not the source of mesh peer subscriptions. The messaging mesh stores subscriptions in a durable Consul-KV store (fluens/<ClusterId>/subscriptions/<app>) read over the same IConsulClient this library registers, so a peer going health-critical drops from the catalog without dropping from the mesh's owed-app set. Because that KV store is not re-derivable from a fresh Consul, run Consul persistently (-server -bootstrap-expect=1 -data-dir + a named volume), never -dev, wherever mesh durability is load-bearing.

Contributor model

A sibling library can advertise additive tags/meta into this application's registration without Discovery depending on it, by registering an IServiceRegistrationContributor:

internal sealed class MeshContributor : IServiceRegistrationContributor
{
    public ServiceRegistrationContribution Contribute() =>
        new(["fluens-mesh"], new Dictionary<string, string>(StringComparer.Ordinal));
}

services.AddSingleton<IServiceRegistrationContributor, MeshContributor>();

Contributions merge into the descriptor with auto → contributor → user precedence; tags are unioned with ordinal de-duplication. The mesh uses this to add the fluens-mesh tag so peers can be discovered by tag.

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 (2)

Showing the top 2 NuGet packages that depend on Fluens.Web.Discovery:

Package Downloads
Fluens.Web.Messaging

P2P HTTP/Protobuf mesh adapter for cross-application Fluens messaging, with shared-key signed cluster authentication.

Fluens.Web.Messaging.Dashboard

Cluster-wide monitoring surface for the Fluens cross-application messaging mesh: dead-letter queries, inbox lag, and stats snapshots.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.7.4 49 6/18/2026
0.7.2 58 6/18/2026
0.7.1 50 6/18/2026