EventStore for Orleans Grain Persistence

EventStore for Orleans Grain PersistenceIn my previous post, I used the JournaledGrain to create an Event Sourced grain.  This enabled us to raise events from within our grain which would be applied to our grain state.  Next up, which I’m covering in this post is how to use EventStore for Orleans Grain Persistence.

This means when we raise events, they will also be persisted to EventStore.  When our grain is activated, we can re-hydrate it by retrieving prior events from an EventStore stream and re-running them in our Grain to get back to current state.

Blog Post Series:

EventStore

If you are unfamiliar with EventStore:

The open-source, functional database with Complex Event Processing in JavaScript.

If you don’t have a running instance, the easiest way is probably with Docker.  Pull down the latest image from docker hub and  as single node running.

docker pull eventstore/eventstore

docker run –name eventstore-node -it -p 2113:2113 -p 1113:1113 eventstore/eventstore

There is a .NETStandard 2.0 compatible client package that I will be using in our Grain Project.

Install-Package EventStore.ClientAPI.NetCore

Writing to EventStore

Anytime our grain was calling the JournaledGrain.RaiseEvent, we want to actually persist that to an EventStore Stream.  For my demo, we will have one EventStore stream per instance of an Orleans grain.  Meaning each bank account will have one event stream.

I’m going to create a new RaiseEvent method that will call the base.RaiseEvent and once confirmed they were applied, append them to our EventStore Stream.  The additional private static methods are really just helpers for (de)serializing our events from/to json.

Re-hydrating

When our Grain activates with OnActivateAsync, this is when we will fetch all the events from our event stream and apply them to our grain.  Basically this will be replaying all the events to build our grain state back up to current state.

 

More!

If you want to try the demo, all the source is available on my PracticalOrleans GitHub Repo.

Do you have any questions or comments? Are you using Orleans or EventStore?  I’d love to hear about it in the comments or on Twitter.

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Event Sourced Orleans Grain

Event Sourced GrainI always thought a Event Sourced Orleans Grain would fit a really well as a stateful Aggregate Root.  Take it a step further and have your Grain be event sourced and also encapsulate a projection of current state.  This post is going to setup the basics of how to Raise events and apply them in our Grain state.  I will be covering persisting the events in the next post.

Blog Post Series:

Event Sourced Grain

I’m going to create a typical example using a bank account.  There are basically two events we will raise.  Deposited event to indicated that we have deposited money into the account and and Withdrawn event to that we have taken money out of the account.

Orleans provides a package Microsoft.Orleans.EventSourcing  to help raise events from you Grain as well as apply them to the state.  From the package, you now can have your grain derive from JournaledGrain<TState, TEvent>.

Grain State

From the example Grain above we are missing our actual grain state, which really a projection so we can keep our current balance.  Once an event is Raised the Grain will call the appropriate Apply(T evnt) method in our state.

Persistence

Next I’ll be persisting our events to Event Store.  This will include once a grain is activated, to pull the events and replay them to get to current state.

More!

If you want to try the demo, all the source is available on my PracticalOrleans GitHub Repo.

Do you have any questions or comments? Are you using Orleans?  I’d love to hear about it in the comments or on Twitter.

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Orleans Smart Cache Pattern

Orleans Smart Cache PatternI discovered the Orleans Smart Cache Pattern by listening to a talk by John Azariah and Sergey Bykov.  The idea is that you can use Orleans as a distributed cache in front of (permanent) storage.  This is really ideal if you have a read heavy system, which most are.  You could optionally also choose to buffer your writes when you make state changes.  Ultimately you will reduce load on your storage by accessing data/state from memory.

Blog Post Series:

Video Tutorial

 

State Holder Grain

The idea is we are going to create a Grain that will be used for holding/containing our state.  There are just two methods, setting and getting our state as defined in IStateHolderGrain<T>

Implementation

For this example, I’m creating a POCO CustomerState to hold some customer data.

Then create a ICustomerGrain that just extends IStateHolderGrain where T is our POCO CustomerState.

Our concrete class CustomerGrain that implements that new ICustomerGrain.

Lastly I created a CustomerStateService which just contains some static methods that create and retrieve our POCO.

Usage

As per my previous post, I’m using ASP.NET Core with Botwin Middleware for a route endpoint.  From here I can use the CustomerStateService to create and fetch out our data.

Abstraction

One of the benefits is abstraction as we can have a POCO for our state that can be persisted to permanent storage.  There’s no dependency of Orleans in our POCO or Botwin Module.

Also we have an immediate consistent cache.  If we were to expose methods to modify the state, our grain would persist those to permanent storage when it decides and we are always returning the most up to date state.

More!

If you want to try the demo, all the source is available on my PracticalOrleans GitHub Repo.

Do you have any questions or comments? Are you using Orleans?  I’d love to hear about it in the comments or on Twitter.

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.