Skip to content
Mark Seemann edited this page Jan 25, 2015 · 1 revision

The idea behind the Single Writer pattern is that only a single thread is allowed to write to the event stream. On the other hand, since the event stream is immutable, many readers can read concurrently from the event stream. Even if a reader reads from an event stream that's being updated at the same time, it may miss the most recent event, but that doesn't impact the consistency of the event stream (and the next time that reader reads from the event stream, it'll see that new event).

You can use the Actor model to implement the Single Writer pattern.

Single process Writer

If you only have a single process (such as a single application, running on a single machine), you may choose to implement the Single Writer pattern in memory.

You can do that by enqueuing Command messages on a thread-safe queue, such as ConcurrentQueue<T>, and then have a background Task running perpetually, pulling a Command off the queue and writing the resulting Event to the event stream, one at a time.

This is essentially a sketch of how to implement an in-process Actor.

If you're on F# there's a built-in implementation of the Actor model. Although the type to use is officially called MailboxProcessor<T>, most people tend to alias it to Agent<T> instead. For an example, see the Functional Architecture with F# Pluralsight course.

Multiple processes Writer

If you have multiple processes that all potentially may write to the event stream, you'll need to coordinate across those processes to ensure that only one of them writes to a particular event stream. All of them can still read from the event stream, since it's immutable.

You may have multiple processes if you have multiple applications running on the same box, but you'll also have that scenario if you've deployed a single application to multiple machines. This last constellation is very common if you're running a load balanced web site.

The easiest way to coordinate writes is to put Commands on a shared queue. It could be Azure Storage Queues, RabbitMQ, MSMQ, or any other out-of-process queue technology.

You'll then need a single background worker process to pull off messages from that queue one at a time, and write them to the event stream in question.

You can for example set up Azure Web Jobs so that only a Single Writer is active at any time.

Clone this wiki locally