Multi-threading in an Azure PaaS-based REST service using Eventstore client

Hi

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:

    Would people in the know say we are mad to do
    this?
    Are there any additional precautions would we
    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?

Thanks

Andy

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).

Call backs happen on the thread pool with the subscription. I would think you just need to setup the subscription and you are done. We handle thread safety between threads accessing same connection etc.

Not sure if this is helpful to you, but this is what I’m doing (and I’ve had no concurrency issues)

For the MVC website I have an Owin Startup class where I subscribe to eventstore:

public void Configuration(IAppBuilder app)
{
//Connect to Eventstore
_connection = GetEventstoreConnectionAsync().Result;
_connection.Disconnected += Connection_Dropped;
_connection.Connected += Connection_Connected;
//Boostrap Event Handlers
BootstrapHandlers(_connection);

Subscribe(Position.Start);
//Owin middleware
ConfigureAuth(app);
}

private void Subscribe(Position position)
{
_subscription = _connection.SubscribeToAllFrom(position,
false,
EventAppeared,
LiveProcessingReached,
SubscriptionDropped,
new UserCredentials(_eventstoreUsername, _eventstorePassword));

}

private static void EventAppeared(EventStoreCatchUpSubscription subscription, ResolvedEvent resolvedEvent)
{
if (resolvedEvent.OriginalStreamId.Contains("$")) return;

        var @event = EventSerialization.DeserializeEvent(resolvedEvent.OriginalEvent);

EventDispatcher.Dispatch(@event as IEvent);
}

In my Event Handlers I’m creating in-memory collections of my view models and exposing them to the client using OData services.

I also have persistent data for my Data warehouse. To do this I’ve used Azure Webjobs. The Webjob gets deployed along with the website. The Webjob has its own subscription to eventstore and persists data to SQL Server (using dapper).

I was originally going to use a worker role but webjobs seem easier to deploy and are a bit more cost effective.

Thanks Marc. This is pretty much where we ended up so it was good to get some validation of the approach.