Orleans Health Checks using ASP.NET Core

Orleans Health Checks

One of the nicest things with the introduction of the Generic Host in Orleans v3.0 is that it allows you to run Orleans side by side with ASP.NET Core. One of the main benefits that I could think of is creating Orleans health checks using ASP.NET Core Health Checks.

Co-Hosting

Since Orleans 3.0, there is now support for the GenericHost via extensions on IHostBuilder, this allows you to run multiple services within the same process all sharing things such as logging, services, configuration, etc.

In a recent blog post, I covered how you can co-host Orleans and ASP.NET Core. This post is an extension of that. If you have not read that already, go take a look first.

ASP.NET Core Health Checks

The reason for wanting health checks for services like an Orleans Silo are varied. One primary use case is when running a silo that is hosted under some type of container orchestration, such as Kubernetes, AWS ECS, etc.

These orchestrators generally provide a mechanism to determine if your service is healthy or unhealthy. If unhealthy, the will create new instances based on your configuration.

ASP.NET Core has a middleware that simplifies providing such health status. I’ve blogged about creating ASP.NET Core Health Checks over on the Telerik Blog.

Orleans Health Checks

In order to verify that a local silo is healthy, we are going to use a stateless grain. The reason being, stateless grains are always executed locally.

Requests made to Stateless Worker grains are always executed locally, that is on the same silo where the request originated, either made by a grain running on the silo or received by the silo’s client gateway. Hence, calls to Stateless Worker grains from other grains or from client gateways never incur a remote message.

Our grain isn’t really doing anything, and it doesn’t need to. I’ve made it return a bool however, it could just return a Task. Returning a bool might be useful if you plan on doing any other check within the grain, such as maybe verify connections to db, etc.

Next, we’ll create our actual ASP.NET Core Health Check by implementing the IHealthCheck.

All our implementation is going to do is get the IHealthCheckGrain. If anything fails, we’ll return Unhealthy, otherwise its all good so we’ll return Healthy.

As you can see, I also added an extension method off of IHealthChecksBuilder just to simplify registering our new health check.

Finally, to wire up our new health check, we need to add AddHealthChecks and AddOrleansHealthCheck to our ConfigureServices. As well we need to call UseHealthChecks in the Configure method.

Results

Now if you browse or make an HTTP call to the /health endpoint, you get a 200 OK with Healthy if the local silo is running.

Related Links

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Co-Hosting Orleans and ASP.NET Core

Orleans and ASP.NET Core

With the release of Orleans 3.0 comes the ability to co-host with ASP.NET Core (or any other framework that uses the generic host builder).

What this means is you can run Orleans and ASP.NET Core in the same process.

The advantage to this is both services will share the same service provider, logging, etc that is configured with the host builder.

Orleans and ASP.NET Core

The extension method UseOrleans() is available now on the IHostBuilder. Just like you would configure the ASP.NET Core via ConfigureWebHostDefaults, you can configure the Orleans silo.

Benefits

One of the nice benefits here is that because both services share service registrations, an ASP.NET Core MVC controller can have the IClusterClient injected into it.

Also since logging is configured it is shared between both ASP.NET Core and Orleans. When I run my demo application, you can see both services in my console logs.

Health Checks

Another benefit of co-hosting Orleans and ASP.NET Core is you can provide a frontend via ASP.NET Core to expose status of your Orleans silo. I’ve written about the ASP.NET Core Health Checks over on the Telerik Blog.

If you’re running in something Docker, AWS ECS or Kubernetes, this would provide you information to determine the health/liveness of your services

Orleans 3.0

If you want more info on the 3.0 release, check out the Announcement for all the details.

Also, check out other related posts:

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

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.