I have a question around the use of the .NET Eventstore client as part of an Azure Web or Worker Role when also accepting inbound REST calls.
As part of our architecture we are migrating towards more
fine-grained read models. Each service implementation of a read model has
essentially two parts: an event handler which listens on an Eventstore
connection and updates the read model, and a REST service that allows clients
to access the data represented in the read model. One option we have is to use persistent
read models (e.g. storing the information in table storage) and have two
components associated with the persistent store: a REST service that reads from
it and an event handler that writes to it. However, we then have two things to
deploy and a chunk of storage to manage for each instance of the service. To
reduce the number of moving parts and simplify the infrastructure, we would
like most of these services to hold their data in memory, probably some form of
Hashmap at its simplest. This means that we would have events being delivered
and inbound REST calls in the same memory space (think hexagonal with two primary adapters). Questions then arise around
thread management and thread safety.
Our current approach has REST services hosted in Web roles.
In this case, the threads in our REST service handling code are spawned and
managed by the container and we observe usual ASP- and MVC-based conventions
around shared data (pretty much not having any or letting the container manage
shared state) to avoid any problems.
The Eventstore .net client works in an async way (we pass it
a callback location for it to deliver events to us) so it will await the event
arrival and resume its processing when one arrives and it is allotted some
thread time. The implication is that it must have access to some underlying
thread on which it can do its async work (blocking/polling and delivering
events to our code).
One option would be to create the Eventstore client in our
main worker thread before it goes into its usual sleep/wait loop. This would
mean that we have both the event handling thread (the main worker thread?) and
one (or more?) threads servicing inbound REST calls.
A second option would be to use a worker role and to
self-host the REST service using OWIN.
In both cases:
need to take to ensure thread safety when accessing the shared state?
Is one preferable to the other?
Are both options equally “not recommended”?
Are we missing an obvious alternative?