-
Notifications
You must be signed in to change notification settings - Fork 14
Single Writer
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.
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.
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.