Skip to content
kc@kumarChandrachooda.com:~$ cd /blog/archive && read --section="top" 0%
Archive

Every article

Newest first, grouped by year. Search or filter by topic.

  • 556 articles
  • 13 matching
Architecture 16 Jan 2026

Compensation That Cannot Fire

Inflow's one real saga has four compensation methods and no message that can ever trigger them. Its state lives in memory, its ordering rests on an undocumented property of a background service, and its failure mode is a denied bonus recorded as success.

Architecture 15 Jan 2026

A Saga Held Together by a String

Inflow's withdrawal flow is a three-module round trip with a compensating branch and no saga class. The correlation between the halves is a magic string declared three times and a JSON blob written by hand on one side and deserialised on the other.

Microservices 16 Dec 2025

A Saga That Cannot Compensate

Trill's ad-publication saga implements Compensating Action in five overrides and can reach none of them - the rejection events it subscribes to carry no correlating id, their handlers return Task.CompletedTask, and no handler ever throws.

.NET 02 Nov 2025

The Saga That Rides a Header

OrderMaker drives a whole order through a Chronicle saga and reports its progress in a single RabbitMQ header - stamped on every publish, forwarded by seven copied MessageBrokers, read back by Operations, and backed by a saga store that forgets everything on restart.

.NET 28 Jun 2025

Reading the Redis and Mongo Providers

Chronicle ships two persistence integrations, and reading them against the contract is a masterclass in provider sharp edges: a Redis key built from Type.GetHashCode() that changes on every restart, a Mongo delete-then-insert, and messages that may not survive the round trip.

.NET 28 Jun 2025

When a Saga Library Is Overkill

Eight parts of source-reading later, the honest retrospective. What Chronicle gets right, the timeout-shaped hole at its centre, how it stacks up against MassTransit and NServiceBus and durable execution - and the cases where a status column beats every saga framework ever written.

.NET 27 Jun 2025

Where a Saga Keeps Its Memory

Chronicle's persistence surface is two interfaces - a state repository and an append-only log - and the defaults behind AddChronicle() are two Lists. What the contracts really demand, why the in-memory implementations are sharper than they look, and how to write a provider that holds up.

.NET 26 Jun 2025

Compensation Is a Replay in Reverse

When a Chronicle saga rejects, the saga log is replayed backwards and every handled message gets its CompensateAsync called. Tracing both rejection paths through the source reveals a surprise - only one of them actually compensates - plus a ForEach that never awaits.

.NET 25 Jun 2025

Four Small Classes Run Every Saga

Seeker, initializer, processor, post-processor - Chronicle's whole runtime is four internal classes you can read in ten minutes. A source walk through the pipeline, including the gate that drops messages, the finally block that always persists, and the state that isn't as final as it looks.

.NET 25 Jun 2025

One Message, Many Sagas

services.AddChronicle() registers sagas you never mentioned, and one ProcessAsync call can run five of them in parallel. Inside Chronicle's Scrutor scan, the seeker's dedupe trick, and the ref-counted lock that serializes each saga id.

.NET 24 Jun 2025

How a Message Finds Its Saga

Correlation is the part of the saga pattern that fails silently. SagaId, SagaContext, the Empty-context trap that starts a new saga per message, and the one-method override that routes messages by their own content.

.NET 23 Jun 2025

The Transaction That Outlives the Request

Split one database into five services and the transaction you deleted does not disappear - it goes feral. On sagas, compensation, process managers, and Chronicle, the small open-source .NET library this series reads line by line.

.NET 23 Jun 2025

Two Interfaces and a Base Class

Chronicle's entire programming model is Saga<TData>, ISagaStartAction, and ISagaAction. Building a full order-fulfilment saga to learn what Complete() promises, what Reject() actually does, and why a saga can have more than one beginning.