Skip to content

Commit

Permalink
Version 1.0.3 Release
Browse files Browse the repository at this point in the history
Version 1.0.3 Release
  • Loading branch information
Arkatufus authored Feb 8, 2023
2 parents ed8e41a + 1cbd18e commit 57d534d
Show file tree
Hide file tree
Showing 28 changed files with 1,166 additions and 80 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ tools/
_site/
api/

# Approval test outputs
*.received.txt
*.txt.bak

## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
Expand Down
163 changes: 137 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
# Akka.Hosting

> **BETA**: this project is currently in beta status as part of the [Akka.NET v1.5 development effort](https://getakka.net/community/whats-new/akkadotnet-v1.5.html), but the packages published in this repository will be backwards compatible for Akka.NET v1.4 users.
> This package is now stable.
HOCON-less configuration, application lifecycle management, `ActorSystem` startup, and actor instantiation for [Akka.NET](https://getakka.net/).

# Supported Packages

Consists of the following packages:

1. `Akka.Hosting` - core, needed for everything
2. `Akka.Remote.Hosting` - enables Akka.Remote configuration
3. [`Akka.Cluster.Hosting`](src/Akka.Cluster.Hosting/README.md) - used for Akka.Cluster, Akka.Cluster.Sharding, and Akka.Cluster.Tools
4. `Akka.Persistence.SqlServer.Hosting` - used for Akka.Persistence.SqlServer support.
5. `Akka.Persistence.PostgreSql.Hosting` - used for Akka.Persistence.PostgreSql support.
6. [`Akka.Persistence.Azure.Hosting`](https://github.com/petabridge/Akka.Persistence.Azure) - used for Akka.Persistence.Azure support. Documentation can be read [here](https://github.com/petabridge/Akka.Persistence.Azure/blob/master/README.md)
7. [The Akka.Management Project Repository](https://github.com/akkadotnet/Akka.Management) - useful tools for managing Akka.NET clusters running inside containerized or cloud based environment. `Akka.Hosting` is embedded in each of its packages:
* [`Akka.Management`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/management/Akka.Management) - core module of the management utilities which provides a central HTTP endpoint for Akka management extensions.
* [`Akka.Management.Cluster.Bootstrap`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/cluster.bootstrap/Akka.Management.Cluster.Bootstrap) - used to bootstrap a cluster formation inside dynamic deployment environments, relies on `Akka.Discovery` to function.
* [`Akka.Discovery.AwsApi`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/discovery/aws/Akka.Discovery.AwsApi) - provides dynamic node discovery service for AWS EC2 environment.
* [`Akka.Discovery.Azure`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/discovery/azure/Akka.Discovery.Azure) - provides a dynamic node discovery service for Azure PaaS ecosystem.
* [`Akka.Discovery.KubernetesApi`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/discovery/kubernetes/Akka.Discovery.KubernetesApi) - provides a dynamic node discovery service for Kubernetes clusters.
* [`Akka.Coordination.KubernetesApi`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/coordination/kubernetes/Akka.Coordination.KubernetesApi) - provides a lease-based distributed lock mechanism for Akka Split Brain Resolver, Akka.Cluster.Sharding, and Akka.Cluster.Singleton
1. `Akka.Hosting` - the core `Akka.Hosting` package, needed for everything
2. [`Akka.Remote.Hosting`](src/Akka.Remote.Hosting) - enables Akka.Remote configuration. Documentation can be read [here](src/Akka.Remote.Hosting/README.md)
3. [`Akka.Cluster.Hosting`](src/Akka.Cluster.Hosting) - used for Akka.Cluster, Akka.Cluster.Sharding, and Akka.Cluster.Tools. Documentation can be read [here](src/Akka.Cluster.Hosting/README.md)
4. [`Akka.Persistence.Hosting`](src/Akka.Persistence.Hosting/README.md) - used for adding persistence functionality to perform local database-less testing. Documentation can be read [here](src/Akka.Persistence.Hosting/README.md)
5. [`Akka.Persistence.SqlServer.Hosting`](src/Akka.Persistence.SqlServer.Hosting) - used for Akka.Persistence.SqlServer support. Documentation can be read [here](src/Akka.Persistence.SqlServer.Hosting/README.md)
6. [`Akka.Persistence.PostgreSql.Hosting`](src/Akka.Persistence.PostgreSql.Hosting) - used for Akka.Persistence.PostgreSql support. Documentation can be read [here](src/Akka.Persistence.PostgreSql.Hosting/README.md)
7. [`Akka.Persistence.Azure.Hosting`](https://github.com/petabridge/Akka.Persistence.Azure) - used for Akka.Persistence.Azure support. Documentation can be read [here](https://github.com/petabridge/Akka.Persistence.Azure/blob/master/README.md)
8. [`Akka.HealthCheck`](https://github.com/petabridge/akkadotnet-healthcheck) - Embed health check functionality for environments such as Kubernetes, ASP.NET, AWS, Azure, Pivotal Cloud Foundry, and more. Documentation can be read [here](https://github.com/petabridge/akkadotnet-healthcheck/blob/dev/README.md)
9. [The `Akka.Management` Project Repository](https://github.com/akkadotnet/Akka.Management) - useful tools for managing Akka.NET clusters running inside containerized or cloud based environment. `Akka.Hosting` is embedded in each of its packages:
* [`Akka.Management`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/management/Akka.Management) - core module of the management utilities which provides a central HTTP endpoint for Akka management extensions. Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/tree/dev/src/management/Akka.Management#akka-management)
* `Akka.Management.Cluster.Bootstrap` - used to bootstrap a cluster formation inside dynamic deployment environments. Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/tree/dev/src/management/Akka.Management#akkamanagementclusterbootstrap)
> **NOTE**
>
> As of version 1.0.0, cluster bootstrap came bundled with the core `Akka.Management` NuGet package and are part of the default HTTP endpoint for `Akka.Management`. All `Akka.Management.Cluster.Bootstrap` NuGet package versions below 1.0.0 should now be considered deprecated.
* [`Akka.Discovery.AwsApi`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/discovery/aws/Akka.Discovery.AwsApi) - provides dynamic node discovery service for AWS EC2 environment. Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/blob/dev/src/discovery/aws/Akka.Discovery.AwsApi/README.md)
* [`Akka.Discovery.Azure`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/discovery/azure/Akka.Discovery.Azure) - provides a dynamic node discovery service for Azure PaaS ecosystem. Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/blob/dev/src/discovery/azure/Akka.Discovery.Azure/README.md)
* [`Akka.Discovery.KubernetesApi`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/discovery/kubernetes/Akka.Discovery.KubernetesApi) - provides a dynamic node discovery service for Kubernetes clusters. Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/blob/dev/src/discovery/kubernetes/Akka.Discovery.KubernetesApi/README.md)
* [`Akka.Coordination.KubernetesApi`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/coordination/kubernetes/Akka.Coordination.KubernetesApi) - provides a lease-based distributed lock mechanism backed by [Kubernetes CRD](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/) for [Akka.NET Split Brain Resolver](https://getakka.net/articles/clustering/split-brain-resolver.html), [Akka.Cluster.Sharding](https://getakka.net/articles/clustering/cluster-sharding.html), and [Akka.Cluster.Singleton](https://getakka.net/articles/clustering/cluster-singleton.html). Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/blob/dev/src/coordination/kubernetes/Akka.Coordination.KubernetesApi/README.md)
* [`Akka.Coordination.Azure`](https://github.com/akkadotnet/Akka.Management/tree/dev/src/coordination/azure/Akka.Coordination.Azure) - provides a lease-based distributed lock mechanism backed by [Microsoft Azure Blob Storage](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-overview) for [Akka.NET Split Brain Resolver](https://getakka.net/articles/clustering/split-brain-resolver.html), [Akka.Cluster.Sharding](https://getakka.net/articles/clustering/cluster-sharding.html), and [Akka.Cluster.Singleton](https://getakka.net/articles/clustering/cluster-singleton.html). Documentation can be read [here](https://github.com/akkadotnet/Akka.Management/blob/dev/src/coordination/azure/Akka.Coordination.Azure/README.md)

See the ["Introduction to Akka.Hosting - HOCONless, "Pit of Success" Akka.NET Runtime and Configuration" video](https://www.youtube.com/watch?v=Mnb9W9ClnB0) for a walkthrough of the library and how it can save you a tremendous amount of time and trouble.

## Summary
# Summary

We want to make Akka.NET something that can be instantiated more typically per the patterns often used with the Microsoft.Extensions.Hosting APIs that are common throughout .NET.

Expand Down Expand Up @@ -93,7 +101,7 @@ builder.Services.AddAkka("MyActorSystem", configurationBuilder =>
})
```

## Dependency Injection Outside and Inside Akka.NET
# Dependency Injection Outside and Inside Akka.NET

One of the other design goals of Akka.Hosting is to make the dependency injection experience with Akka.NET as seamless as any other .NET technology. We accomplish this through two new APIs:

Expand All @@ -102,19 +110,37 @@ One of the other design goals of Akka.Hosting is to make the dependency injectio

> **N.B.** The `ActorRegistry` and the `ActorSystem` are automatically registered with the `IServiceCollection` / `IServiceProvider` associated with your application.
### Registering Actors with the `ActorRegistry`
## Registering Actors with the `ActorRegistry`

As part of Akka.Hosting, we need to provide a means of making it easy to pass around top-level `IActorRef`s via dependency injection both within the `ActorSystem` and outside of it.

The `ActorRegistry` will fulfill this role through a set of generic, typed methods that make storage and retrieval of long-lived `IActorRef`s easy and coherent:

* Fetch ActorRegistry from ActorSystem manually
```csharp
var registry = ActorRegistry.For(myActorSystem);
```

* Provided by the actor builder
```csharp
builder.Services.AddAkka("MyActorSystem", configurationBuilder =>
{
configurationBuilder
.WithActors((system, actorRegistry) =>
{
var actor = system.ActorOf(Props.Create(() => new MyActor));
actorRegistry.TryRegister<MyActor>(actor); // register actor for DI
});
});
```

* Obtaining the `IActorRef` manually
```csharp
var registry = ActorRegistry.For(myActorSystem); // fetch from ActorSystem
registry.TryRegister<Index>(indexer); // register for DI
var registry = ActorRegistry.For(myActorSystem);
registry.Get<Index>(); // use in DI
```

### Injecting Actors with `IRequiredActor<TKey>`
## Injecting Actors with `IRequiredActor<TKey>`

Suppose we have a class that depends on having a reference to a top-level actor, a router, a `ShardRegion`, or perhaps a `ClusterSingleton` (common types of actors that often interface with non-Akka.NET parts of a .NET application):

Expand Down Expand Up @@ -171,7 +197,7 @@ using var host = new HostBuilder()

Adding your actor and your type key into the `ActorRegistry` is sufficient - no additional DI registration is required to access the `IRequiredActor<TActor>` for that type.

#### Resolving `IRequiredActor<TKey>` within Akka.NET
### Resolving `IRequiredActor<TKey>` within Akka.NET

Akka.NET does not use dependency injection to start actors by default primarily because actor lifetime is unbounded by default - this means reasoning about the scope of injected dependencies isn't trivial. ASP.NET, by contrast, is trivial: all HTTP requests are request-scoped and all web socket connections are connection-scoped - these are objects have _bounded_ and typically short lifetimes.

Expand Down Expand Up @@ -201,11 +227,96 @@ builder.Services.AddAkka("MyActorSystem", configurationBuilder =>

The `dependencyResolver.Props<MySingletonDiActor>()` call will leverage the `ActorSystem`'s built-in `IDependencyResolver` to instantiate the `MySingletonDiActor` and inject it with all of the necessary dependences, including `IRequiredActor<TKey>`.

## Microsoft.Extensions.Logging Integration
# Microsoft.Extensions.Configuration Integration

## IConfiguration To HOCON Adapter

The `AddHocon` extension method can convert `Microsoft.Extensions.Configuration` `IConfiguration` into HOCON `Config` instance and adds it to the ActorSystem being configured.
* All variable name are automatically converted to lower case.
* All "." (period) in the `IConfiguration` key will be treated as a HOCON object key separator
* For environment variable configuration provider:
* "__" (double underline) will be converted to "." (period).
* "_" (single underline) will be converted to "-" (dash).
* If all keys are composed of integer parseable keys, the whole object is treated as an array

__Example:__

`appsettings.json`:

```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"akka": {
"cluster": {
"roles": [ "front-end", "back-end" ],
"min-nr-of-members": 3,
"log-info": true
}
}
}
```

Environment variables:

```powershell
AKKA__ACTOR__TELEMETRY__ENABLED=true
AKKA__CLUSTER__SEED_NODES__0=akka.tcp//mySystem@localhost:4055
AKKA__CLUSTER__SEED_NODES__1=akka.tcp//mySystem@localhost:4056
AKKA__CLUSTER__SEED_NODE_TIMEOUT=00:00:05
```

Example code:

```csharp
/*
Both appsettings.json and environment variables are combined
into HOCON configuration:
akka {
actor.telemetry.enabled: on
cluster {
roles: [ "front-end", "back-end" ]
seed-nodes: [
"akka.tcp//mySystem@localhost:4055",
"akka.tcp//mySystem@localhost:4056"
]
min-nr-of-members: 3
seed-node-timeout: 5s
log-info: true
}
}
*/
var host = new HostBuilder()
.ConfigureHostConfiguration(builder =>
{
// Setup IConfiguration to load from appsettings.json and
// environment variables
builder
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
})
.ConfigureServices((context, services) =>
{
services.AddAkka("mySystem", (builder, provider) =>
{
// convert IConfiguration to HOCON
var akkaConfig = context.Configuration.GetSection("akka");
builder.AddHocon(akkaConfig, HoconAddMode.Prepend);
});
});
```

# Microsoft.Extensions.Logging Integration

__Logger Configuration Support__
## Logger Configuration Support

You can now use the new `AkkaConfigurationBuilder` extension method called `ConfigureLoggers(Action<LoggerConfigBuilder>)` to configure how Akka.NET logger behave.
You can use `AkkaConfigurationBuilder` extension method called `ConfigureLoggers(Action<LoggerConfigBuilder>)` to configure how Akka.NET logger behave.

Example:
```csharp
Expand Down Expand Up @@ -260,11 +371,11 @@ Currently supported logger methods:
- `AddDefaultLogger()`: Add the default Akka.NET console logger.
- `AddLoggerFactory()`: Add the new `ILoggerFactory` logger.

### Microsoft.Extensions.Logging.ILoggerFactory Logging Support
## Microsoft.Extensions.Logging.ILoggerFactory Logging Support

You can now use `ILoggerFactory` from Microsoft.Extensions.Logging as one of the sinks for Akka.NET logger. This logger will use the `ILoggerFactory` service set up inside the dependency injection `ServiceProvider` as its sink.

### Microsoft.Extensions.Logging Log Event Filtering
## Microsoft.Extensions.Logging Log Event Filtering

There will be two log event filters acting on the final log input, the Akka.NET `akka.loglevel` setting and the `Microsoft.Extensions.Logging` settings, make sure that both are set correctly or some log messages will be missing.

Expand Down
38 changes: 37 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
## [1.0.3] / 8 February 2023

Version 1.0.3 fixes a bug in the HOCON configuration generator where it did not generate the proper escape characters for the generated HOCON string.

* [Fix HOCON generator](https://github.com/akkadotnet/Akka.Hosting/pull/207)

## [1.0.2] / 31 January 2023

Version 1.0.2 introduces a new method to the `ActorRegistry.GetAsync` in order to allow users to force parts of their application to wait until a specific `IActorRef` has been started and added to the `ActorRegistry`.

```csharp
// arrange
var registry = new ActorRegistry();

// act
var task = registry.GetAsync<Nobody>();
task.IsCompletedSuccessfully.Should().BeFalse();

registry.Register<Nobody>(Nobody.Instance);
var result = await task;

// assert
result.Should().Be(Nobody.Instance);
```

This method is designed to allow users to wait via `async Task<IActorRef>` for an actor to be registered in the event that a specific `IRequiredActor<TKey>` is needed before Akka.Hosting can start the `ActorSystem` inside its `IHostedService`.

## [1.0.1] / 6 January 2023

Version 1.0.1 fixes options bug used in the cluster sharding Akka.Hosting extension method.

* [Update Akka.NET from 1.4.45 to 1.4.48](https://github.com/akkadotnet/akka.net/releases/tag/1.4.48)
* [Fix SimpleDemo project failing on `Development` environment](https://github.com/akkadotnet/Akka.Hosting/pull/184)
* [Add F# CustomJournalIdDemo project](https://github.com/akkadotnet/Akka.Hosting/pull/183)
* [Fix cluster sharding hosting extension method options bug](https://github.com/akkadotnet/Akka.Hosting/pull/186)

## [1.0.0] / 27 December 2022

This 1.0.0 release is the RTM release for `Akka.Hosting` and contains major API breaking changes with a lot of its API. All current API will be frozen for all future releases and will be backed with our backward compatibility promise.
Expand Down Expand Up @@ -314,4 +350,4 @@ This feature is useful when a user need to run a specific initialization code if

For example, this feature is useful for:
- kicking off actor initializations by using Tell()s once all of the actor infrastructure are in place, or
- pre-populating certain persistence or database data after everything is set up and running, useful for unit testing or adding fake data for local development.
- pre-populating certain persistence or database data after everything is set up and running, useful for unit testing or adding fake data for local development.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<ItemGroup>
<PackageReference Include="Akka.TestKit.Xunit2" Version="$(AkkaVersion)" />
<PackageReference Include="FluentAssertions" Version="6.8.0" />
<PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftExtensionsVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
Expand Down
4 changes: 2 additions & 2 deletions src/Akka.Cluster.Hosting/AkkaClusterHostingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@ private static ClusterShardingSettings PopulateClusterShardingSettings(ShardOpti

if (shardOptions.StateStoreMode == StateStoreMode.Persistence)
settings = settings
.WithJournalPluginId(shardOptions.JournalOptions?.Identifier ?? shardOptions.JournalPluginId)
.WithSnapshotPluginId(shardOptions.SnapshotOptions?.Identifier ?? shardOptions.SnapshotPluginId);
.WithJournalPluginId(shardOptions.JournalOptions?.PluginId ?? shardOptions.JournalPluginId)
.WithSnapshotPluginId(shardOptions.SnapshotOptions?.PluginId ?? shardOptions.SnapshotPluginId);
return settings;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Akka.Hosting.API.Tests/Akka.Hosting.API.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="PublicApiGenerator" Version="10.3.0" />
<PackageReference Include="Verify.Xunit" Version="19.5.0" />
<PackageReference Include="Verify.DiffPlex" Version="2.0.1" />
<PackageReference Include="Verify.Xunit" Version="19.9.2" />
<PackageReference Include="Verify.DiffPlex" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 57d534d

Please sign in to comment.