Skip to content

Commit

Permalink
Merge branch 'master' into bash-scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaronontheweb authored Mar 26, 2024
2 parents 07137f7 + 14fa304 commit 596bda4
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 5 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ These samples aren't designed to teach how to model complex domains using actors

1. [Akka.NET Cluster.Sharding with Akka.Persistence.SqlServer and Razor Pages](https://github.com/petabridge/akkadotnet-code-samples/tree/master/src/clustering/sharding-sqlserver)
2. [Akka.Streams.Amqp.RabbitMQ with Akka.Cluster.Sharding - Reliable Delivery + Backpressure Support](https://github.com/petabridge/akkadotnet-code-samples/tree/master/src/reliability/rabbitmq-backpressure)
3. [Event-Sourcing and CQRS with Akka.Peristence and Akka.Peristence.Query](https://github.com/petabridge/akkadotnet-code-samples/tree/master/src/cqrs/cqrs-sqlserver)

## Contributing

Expand Down Expand Up @@ -50,8 +51,7 @@ You are free to modify and use these diagrams in your own derivative works as lo

[Petabridge](https://petabridge.com/) is a company dedicated to making it easier for .NET developers to build distributed applications.

Petabridge provides Akka.NET consulting and training, including advanced training in [Akka.Remote](https://petabridge.com/training/akka-remoting/), [Akka.Cluster](https://petabridge.com/training/akka-clustering/), and [Akka.NET Design Patterns](https://petabridge.com/training/akka-design-patterns/)!
Petabridge provides [Akka.NET support, consulting, and training](https://petabridge.com/services/support/).

---
Copyright 2015 - 2022 Petabridge, LLC

Copyright 2015 - 2024 Petabridge, LLC
4 changes: 2 additions & 2 deletions src/clustering/sharding-sqlserver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ The goal of this sample is to demonstrate how to host Akka.Cluster.Sharding with

This solution is built with:

- .NET 6 minimal APIs;
- Minimal APIs;
- C# `record` types;
- ASP.NET Core 6;
- ASP.NET Core;
- Google.Protobuf for message and state schema;
- Akka.NET v1.5 w/ Akka.Cluster;
- Akka.Persistence.SqlServer; and
Expand Down
91 changes: 91 additions & 0 deletions src/cqrs/cqrs-sqlserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Akka.NET Event-Sourcing and CQRS with Akka.Persistence

The goal of this sample is to demonstrate:

1. How do to basic event-sourcing with Akka.Persistence;
2. How to use Akka.Persistence.Query to project events written to Akka.Persistence; and
3. How to use Entity Framework Core to create CQRS-style read models that are used by the frontend application.

## Technology

This solution is built with:

- Minimal APIs;
- C# `record` types;
- [Blazor](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor) and [MudBlazor](https://www.mudblazor.com/);
- Google.Protobuf for message and state schema;
- Akka.NET v1.5 w/ Akka.Persistence and [Akka.Persistence.Query](https://getakka.net/articles/persistence/persistence-query.html);
- [Entity Framework Core](https://learn.microsoft.com/en-us/ef/core/), for our read models;
- [Akka.Persistence.Sql](https://github.com/akkadotnet/Akka.Persistence.Sql); and
- [Akka.Hosting](https://github.com/akkadotnet/Akka.Hosting) - which minimizes the amount of configuration for Akka.NET to practically zero.

## Domain

Like all of the samples in this repository, we are using a simple domain since the focus of the sample is meant to be _how to use Akka.NET infrastructure succinctly and successfully_. That being said, it's still worth understanding what our domain does: product inventory + revenue tracking. It's the same domain as ["Akka.NET Cluster.Sharding with Akka.Persistence.SqlServer and Razor Pages"](../../clustering/sharding-sqlserver).

> This app does not use Akka.Cluster, although it could be easily modified to do so (nothing would really change other than migrating some actors to `ShardRegion`s and `SingletonManager`s).
In the `CqrsSqlServer.Backend` application:

1. **`ProductTotalsActor`** - our `ReceivePersistentActor` that will process `IProductCommand `, transforming them into (0..N) `IProductEvent`s, updating its `ProductState`, and replying to the original sender with a `ProductCommandResponse` with the results of each command. This entity actor demonstrates one of the more robust ways of executing event-sourcing on top of Akka.Persistence using C#9 `record` types and cleanly separating command / event / query message types from each other.
2. **`ProductProjectorActor`** - a singleton `ReceivePersistentActor` that functions as a projector + materialized view creator for all of the events saved by _all_ of the `ProductTotalsActor` instance. It uses Akka.Persistence.Query's `EventsByTag` functionality to query all of the events tagged by the `MessageTagger` - and then safely renders read models using the `CqrsSqlServerContext` EF Core model.

In the `CqrsSqlServer.Frontend` application, we don't use Akka.NET _at all_ - we just spin up a simple Blazor UI that reads data that reads the `CqrsSqlServerContext` read models.

## Running This Sample

### Launch Dependencies

To run this sample, we first need to spin up our dependencies - a SQL Server instance with a predefined `Akka` database ready to be configured.

**Windows**

```shell
start-dependencies.cmd
```

**Linux or OS X**

```shell
./start-dependencies.sh
```

This will build a copy of our [MSSQL image](https://github.com/petabridge/akkadotnet-code-samples/tree/master/infrastructure/mssql) and run it on port 1533. The sample is already pre-configured to connect to it at startup.

### `dotnet ef` Dependency

`start-dependencies.cmd` and `start-dependencies.sh` will also run `dotnet ef database update` - make sure you have the Entity Framework Core `dotnet` CLI installed!

```shell
dotnet tool install --global dotnet-ef
```

or update to the latest

```shell
dotnet tool update --global dotnet-ef
```
### Run the Sample

First, take a look at the `appSettings.json` for `CqrsSqlServer.Backend.csproj`:

```json
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"SeedDb": true
}
```

Make sure you run with `"SeedDb": true` the first time you launch the application, otherwise it won't do anything.

If you run the application a second time with this setting, some of the random data generated by Bogus might conflict with data already stored inside the application - that should be fine. Those events will just get ignored by the persistent actors.

Launch `CqrsSqlServer.Backend.csproj` via Visual Studio, Rider, or the `dotnet` CLI first.

Then, once that app is running, launch `CqrsSqlServer.Frontend.csproj` and go to http://localhost:5191/

0 comments on commit 596bda4

Please sign in to comment.