- Orleans Kitchen Sink
- Step 0 (Added Empty Solution)
- Step 1 (Hello World)
- Step 2 (Add State)
- Step 3 (Upgrade to .Net 5)
- Step 4 (Add Unit and Integration tests)
- Step 5 (Add Journaled Grain)
- Step 6 (Reminders)
- Todo
- References
Project to learn Microsoft Orleans
Just getting started. Added empty solution and this readme.
Add a new ASP.NET Core API Project.
Add following dependencies
- Microsoft.Orleans.Client
- Microsoft.Orleans.CodeGenerator.MSBuild
- Microsoft.Orleans.Server
Update Program.cs and setup orleans. For now we will use localhost clustering.
Add a new project (.Net standard class library). Add Grain interface with Guid as key. We also need to add following dependencies
- Microsoft.Orleans.Core.Abstractions
- Microsoft.Orleans.CodeGenerator.MSBuild
Add a new .net standard project. Add a new class and implement interface we added in GrainInterfaces
project. Also add following dependencies
- Microsoft.Orleans.CodeGenerator.MSBuild
- Microsoft.Orleans.Core
Add reference to both GrainInterfaces
and Grains
project in API
project.
Update controller to get reference to grain and call SayHello
method. Had to update order of how orleans was being configured in Program.cs
. Configuring Orleans after ConfigureWebHostDefaults
was throwing InvalidSchedulingContextException
For adding state to a grain we need to add a new State class. We will then add the state to Grain. To add state we have two options
- Extend
Grain\<TState\>
class - Inject
IPersistentState\<TState\>
via constructor with[PersistentState("stateName", "providerName")]
attribute. UsingIPersistentState
is preferred so we will use this method. UsingIPersistentState
we can inject multiple state objects. E.g. for a consumer profile we cab inject one for Profile and one for Cart.
Update Grain class to inject [PersistentState("greetingStore","HelloGrainStorage")] IPersistentState<GreetingState> greetings
and then update SayHello method to use the state. We also need to update the interface to update signature of existing SayHello
method and add a new method to get history.
Update Program.cs
and configure storage provider. To begin with we will use in-memory storage.
Upgrade to .Net 5 and use Serilog for logging.
Added unit and integration tests.
Integration tests added for both Orleans and API
Unit tests added for Grains. Used OrleansTestKit for adding Orleans unit tests.
Added one grain that uses EventSourcing (JournaledGrain in orleans). Added relevant integration tests. Looks like Unit Tests for Journaled Grains are not supported. Every thing is using in memory storage for now.
JournaledGrains on receiving a message raise an event. Grain can decide not to raise event (e.g. if message fails validation). Events are then handled in State and result in state change. In our example Ping raises a PingEvent which results in few changes in State. If Ping received is older then last received ping then it is ignored and no event is raised.
One of the changes PingEvent does is to change Device state to Online. There is no Event to change Device state back to Offline. Orleans Reminder looks like a good way to handle this.
Few other minor changes (e.g. renamed OrleansController to HelloController)
Add a reminder to DeviceGrain. Reminder is used to check when last ping was received. If more than 30 minutes have passed then Device state is set to offline. Again we are using in-memory storage for reminders.
Added a new status to device Idle
so updated code and tests to use DeviceStatus based on enum instead of a boolean for online and offline
For accessing Reminder(s) added a FakeReminderRegistry
based on orleans sample and based on discussion here. Kept the integration test for reminders to minimum (just checking if a reminder is added on activation or not). Actual behavior is tested using unit tests.
- How to test JounraledGrains
- Use SQL Server for different storages used by Orleans
- Deploy using Kubernetes
- Add standalone Silo host (separate from Api Service)
- Integrate Orleans Streaming
- Build projections based on events generated by JournaledGrains
- Add support for queries (e.g. total offline grains)
- Push commands to actual device (physical device) using grain
- Add Orleans Dashboard
- Add performance tests
- Add Healthchecks