Hugo 2.0.0
dotnet add package Hugo --version 2.0.0
NuGet\Install-Package Hugo -Version 2.0.0
<PackageReference Include="Hugo" Version="2.0.0" />
<PackageVersion Include="Hugo" Version="2.0.0" />
<PackageReference Include="Hugo" />
paket add Hugo --version 2.0.0
#r "nuget: Hugo, 2.0.0"
#:package Hugo@2.0.0
#addin nuget:?package=Hugo&version=2.0.0
#tool nuget:?package=Hugo&version=2.0.0
Hugo
Go-style concurrency primitives and functional result pipelines for 10 applications.
Table of contents
- Highlights
- When to use Hugo
- Supported runtimes
- Trimming & AOT considerations
- Install
- Quick start
- Observability in one call
- Documentation
- Samples & benchmarks
- Project layout
- Support
- Contributing
- License
Highlights
- Deterministic concurrency: Channels, wait groups, mutexes, RW locks, timers, defer, and select-style helpers mirror Go semantics while respecting
CancellationTokenandTimeProvider. - Railway-oriented results:
Result<T>pipelines keep success/failure explicit withThen,Map,Recover,Ensure, streaming helpers, sagas, and tiered fallbacks. ValueTask-first extensions such asThenValueTaskAsync,MapValueTaskAsync, andTapValueTaskAsynckeep async pipelines allocation-free when your delegates already returnValueTask<Result<T>>. - Observability first:
GoDiagnosticsships counters, histograms, and activity sources that plug directly into OpenTelemetry exporters or custom meter providers. - Source-generated error catalog: Hugo’s well-known error codes are generated at compile time, ensuring consistent metadata for logs, metrics, and documentation.
- Batteries included: Prioritised channels, task queue leasing, retry policies, deterministic version gates, workflow telemetry, and profiling recipes ship alongside the core library.
- Testability: Fakeable time providers, deterministic effect capture, structured errors, and cancellation metadata keep async workflows reproducible in CI.
When to use Hugo
- You need Go-like coordination primitives (channels/select/wait groups) without leaving C#.
- You want predictable error handling with structured metadata instead of exceptions for control flow.
- You are building workflow orchestrations that must replay deterministically across retries and recoveries.
- You plan to publish metrics and traces for concurrency-heavy workloads without custom instrumentation.
- You require reusable timeout/retry/cancellation playbooks that can be enforced across teams.
Supported runtimes
- Targets
net10.0. - Works with generic host builders, ASP.NET background services, worker services, and isolated Azure Functions workers.
- Verified with the .NET 10 SDK;
Trimming & AOT considerations
Hugo is tested with the .NET NativeAOT toolchain and ships with trimming/AOT analyzers enabled, but two APIs depend on System.Text.Json to round-trip arbitrary runtime types:
DeterministicEffectStoreandVersionGatepersist workflow payloads as JSON.Error/ErrorJsonConverterpreserve metadata dictionaries that can contain any CLR object.
When publishing with PublishTrimmed=true or PublishAot=true, make sure the types you capture in effect stores or error metadata aren’t trimmed away. Typical approaches include:
- Prefer source generation – register a
JsonSerializerContextthat lists the effect payloads and pass it toDeterministicEffectStore/VersionGate. - Root the types manually – use
DynamicDependency,PreserveDependency, or reflection registration files to keep rare payloads alive. - Keep metadata simple – favor primitive types, records, or known DTOs in
Error.Metadataso the linker can see them.
If the linker/AOT compiler warns about RequiresUnreferencedCode on these APIs, it means a payload needs to be preserved before trimming continues.
Install
dotnet add package Hugo
- Plays nicely with central package management (
Directory.Packages.props). - To iterate locally, run
dotnet pack src/Hugo/Hugo.csproj -o ./artifactsand point a local feed at the generated.nupkg.
Quick start
These steps mirror the getting started tutorial but demonstrate channels, fan-in coordination, and Result<T> in a single console app.
Bootstrap a sample
dotnet new console -n HugoQuickstart cd HugoQuickstart dotnet add package HugoCompose channels, wait groups, and results
Replace
Program.cswith:using Hugo; using static Hugo.Go; using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); var metrics = MakeChannel<int>(capacity: 8); var jobs = MakeChannel<string>(capacity: 8); var merged = MakeChannel<object>(capacity: 16); var workers = new WaitGroup(); workers.Go(async () => { using var complete = Defer(() => metrics.Writer.TryComplete()); for (var i = 0; i < 3; i++) { await metrics.Writer.WriteAsync(i, cts.Token).ConfigureAwait(false); } }); workers.Go(async () => { using var complete = Defer(() => jobs.Writer.TryComplete()); foreach (var name in new[] { "build", "deploy", "notify" }) { await jobs.Writer.WriteAsync(name, cts.Token).ConfigureAwait(false); } }); var relay = FanInAsync( sources: new[] { metrics.Reader, jobs.Reader }, destination: merged.Writer, completeDestination: true, cancellationToken: cts.Token); var messages = new List<string>(); await foreach (var payload in merged.Reader.ReadAllAsync(cts.Token)) { var result = payload switch { int sample => Ok(sample) .Ensure(static value => value >= 0, value => Error.From($"negative sample {value}", "error.validation")) .Map(static value => $"metric={value}"), string job => Ok(job) .Ensure(static value => !string.IsNullOrWhiteSpace(value)) .Map(static value => $"job={value}"), _ => Err<string>("unsupported payload", "error.validation") }; var handled = await result .TapAsync(static (value, token) => { Console.WriteLine($"processed {value}"); return ValueTask.CompletedTask; }, cts.Token); if (handled.IsSuccess) { messages.Add(handled.Value); } else { Console.WriteLine($"skipped: {handled.Error}"); } } var fanInResult = await relay; if (fanInResult.IsFailure) { Console.WriteLine($"fan-in failed: {fanInResult.Error}"); } await workers.WaitAsync(cts.Token); Console.WriteLine(string.Join(", ", messages));Run it
dotnet runLower the timeout or cancel manually to see how
Error.Canceledflows through the pipeline without throwing.
Extend the sample
- Apply timeout, retry, and cancellation policies with the playbook templates.
- Stream merged channel output into a background worker or
TaskQueue<T>using Coordinate fan-in workflows. - Swap in a fake
TimeProviderto deterministically test deadlines and ticker behaviour. - Wire observability with Publish metrics and traces to OpenTelemetry.
Observability in one call
using Hugo.Diagnostics.OpenTelemetry;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddOpenTelemetry()
.AddHugoDiagnostics(options =>
{
options.ServiceName = builder.Environment.ApplicationName;
options.OtlpEndpoint = new Uri("http://localhost:4317");
options.AddPrometheusExporter = true;
});
var app = builder.Build();
app.Run();
- Metrics:
waitgroup.*,channel.select.*,taskqueue.*,workflow.*,result.*, and more (see Diagnostics reference). - Traces: rate-limited spans that carry workflow metadata and channel coordination tags.
- Ready-made collector recipes live in the worker sample walkthrough.
Documentation
Hugo follows the Divio documentation system so you can find the right level of guidance quickly:
- Tutorials – step-by-step introductions such as Getting started with channels and results.
- How-to guides – task-oriented recipes for fan-in coordination, OpenTelemetry export, workflow visibility, profiling, and retry playbooks.
- Reference – definitive API docs covering concurrency primitives, result pipelines, deterministic coordination, diagnostics, and the full API catalogue.
Start at docs/index.md for navigation and search hints.
Samples & benchmarks
samples/Hugo.WorkerSample– a background worker showcasing task queues, deterministic workflows, and OpenTelemetry integration.benchmarks/Hugo.Benchmarks– BenchmarkDotNet suites comparing Hugo primitives to baseline .NET constructs (mutex vsSemaphoreSlim, prioritized channels, result pipelines, select latency, object pools, timers).
Run the worker sample with a local collector:
docker run --rm \
-p 4317:4317 -p 4318:4318 -p 9464:9464 \
-v "${PWD}/otel-collector.yaml:/etc/otelcol/config.yaml" \
otel/opentelemetry-collector:0.103.1
dotnet run --project samples/Hugo.WorkerSample/Hugo.WorkerSample.csproj
Benchmark results are written to BenchmarkDotNet.Artifacts/results/.
Project layout
src/– library source for concurrency primitives, result pipelines, policies, sagas, deterministic coordination, and diagnostics.tests/– unit, integration, and deterministic timing tests.docs/– tutorials, how-to guides, references, explanations, roadmap, and audit trackers (rendered via DocFX).samples/– runnable end-to-end scenarios.benchmarks/– performance harnesses executed with BenchmarkDotNet.tools/– profiling scripts, analyzers, and auxiliary automation.
Support
- Questions & bugs: open an issue on GitHub.
- Security disclosures: contact the maintainer privately before filing a public issue.
Contributing
- Review CONTRIBUTING.md for environment setup, coding standards, and workflow expectations.
- Run
dotnet build Hugo.slnxanddotnet testfortests/Hugo.UnitTests,tests/Hugo.IntegrationTests, andtests/Hugo.FeatureTestsbefore submitting a pull request. - Collect coverage with
dotnet test --collect:"XPlat Code Coverage"to match CI.
License
Hugo is licensed under the MIT License. Use, modify, and distribute it within those terms.
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- System.Threading.RateLimiting (>= 10.0.0)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on Hugo:
| Package | Downloads |
|---|---|
|
Hugo.Diagnostics.OpenTelemetry
OpenTelemetry extensions and defaults for Hugo diagnostics instrumentation. |
|
|
Hugo.TaskQueues.Replication
Replication helpers, deterministic coordinators, and checkpointing sinks for Hugo task queues. |
|
|
Hugo.Deterministic.Cosmos
Azure Cosmos DB deterministic state store for Hugo workflows. |
|
|
Hugo.Deterministic.Redis
Redis-backed deterministic state store for Hugo workflows. |
|
|
Hugo.TaskQueues.Diagnostics
TaskQueue diagnostics helpers (meters, activity sources, sampling, adapters) for Hugo hosts. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 485 | 11/21/2025 |
| 2.0.0-rc.7 | 308 | 11/21/2025 |
| 2.0.0-rc.6 | 414 | 11/18/2025 |
| 2.0.0-rc.5 | 359 | 11/18/2025 |
| 2.0.0-rc.3 | 346 | 11/18/2025 |
| 1.4.11 | 249 | 11/14/2025 |
| 1.4.10 | 341 | 11/13/2025 |
| 1.4.9 | 357 | 11/12/2025 |
| 1.4.8 | 337 | 11/10/2025 |
| 1.4.7 | 270 | 11/10/2025 |
| 1.4.5 | 259 | 11/10/2025 |
| 1.4.4 | 219 | 11/9/2025 |
| 1.4.3 | 207 | 11/9/2025 |
| 1.4.2 | 254 | 10/30/2025 |
| 1.4.1 | 187 | 10/30/2025 |
| 1.4.0 | 189 | 10/27/2025 |
| 1.3.6 | 191 | 10/27/2025 |
| 1.3.5 | 174 | 10/26/2025 |
| 1.3.4 | 171 | 10/26/2025 |
| 1.3.3 | 142 | 10/25/2025 |
| 1.3.2 | 142 | 10/25/2025 |
| 1.3.0 | 111 | 10/25/2025 |
| 1.1.0 | 153 | 10/24/2025 |
| 1.0.2 | 225 | 10/23/2025 |
| 1.0.1 | 180 | 10/23/2025 |
| 1.0.0 | 244 | 10/21/2025 |
| 0.5.8 | 179 | 10/21/2025 |
| 0.5.7 | 178 | 10/21/2025 |
| 0.5.6 | 175 | 10/21/2025 |
| 0.5.5 | 172 | 10/21/2025 |
| 0.5.4 | 166 | 10/21/2025 |
| 0.5.3 | 174 | 10/21/2025 |
| 0.5.2 | 178 | 10/21/2025 |
| 0.5.0 | 174 | 10/20/2025 |
| 0.4.0 | 175 | 10/20/2025 |
| 0.3.1 | 178 | 10/20/2025 |
| 0.3.0 | 170 | 10/19/2025 |
| 0.2.0 | 182 | 10/19/2025 |
| 0.1.2 | 175 | 10/19/2025 |
| 0.1.0 | 185 | 10/19/2025 |