Skip to content

Commit

Permalink
Merge pull request #2790 from akkadotnet/dev
Browse files Browse the repository at this point in the history
Akka.NET v1.2.1 Production Release
  • Loading branch information
Aaronontheweb authored Jun 23, 2017
2 parents 932a6ba + cc38e5b commit 946dfdc
Show file tree
Hide file tree
Showing 655 changed files with 24,358 additions and 7,096 deletions.
19 changes: 19 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
#### 1.2.1 June 22 2017 ####
**Maintenance Release for Akka.NET 1.2**

Resolves issues related to Akka.Cluster nodes not being able to cleanly leave or join a cluster after a period of network instability.

[See the full set of Akka.NET 1.2.1 fixes here](https://github.com/akkadotnet/akka.net/milestone/14).

| COMMITS | LOC+ | LOC- | AUTHOR |
| --- | --- | --- | --- |
| 15 | 1362 | 753 | alexvaluyskiy |
| 7 | 635 | 1487 | ravengerUA |
| 7 | 1966 | 764 | Nick Chamberlain |
| 4 | 420 | 345 | Aaron Stannard |
| 3 | 18715 | 999 | Alex Valuyskiy |
| 2 | 1943 | 3492 | Sean Gilliam |
| 2 | 104 | 24 | Jaskula Tomasz |
| 1 | 6 | 10 | Szer |
| 1 | 20 | 25 | Lealand Vettleson |

#### 1.2.0 April 11 2017 ####
**Feature Release for Akka.NET**
Akka.NET 1.2 is a major feature release that introduces the following major changes:
Expand Down
11 changes: 7 additions & 4 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,12 @@ Target "CleanTests" <| fun _ ->

open Fake.Testing
Target "RunTests" <| fun _ ->
let xunitTestAssemblies = Seq.filter filterPlatformSpecificAssemblies (!! "src/**/bin/Release/*.Tests.dll" --
let xunitTestAssemblies = Seq.filter filterPlatformSpecificAssemblies (
!! "src/**/bin/Release/*.Tests.dll"
// Akka.Streams.Tests is referencing Akka.Streams.TestKit.Tests
"src/**/Akka.Streams.Tests/bin/Release/Akka.Streams.TestKit.Tests.dll" --
-- "src/**/Akka.Streams.Tests/bin/Release/Akka.Streams.TestKit.Tests.dll"
// Akka.Streams.Tests.Performance is referencing Akka.Streams.Tests and Akka.Streams.TestKit.Tests
"src/**/Akka.Streams.Tests.Performance/bin/Release/*.Tests.dll")
-- "src/**/Akka.Streams.Tests.Performance/bin/Release/*.Tests.dll")

let nunitTestAssemblies = Seq.filter filterPlatformSpecificAssemblies (!! "src/**/bin/Release/Akka.Streams.Tests.TCK.dll")

Expand Down Expand Up @@ -395,7 +396,7 @@ module Nuget =
| "Akka.Persistence.TestKit" -> ["Akka.Persistence", preReleaseVersion; "Akka.TestKit.Xunit2", release.NugetVersion]
| "Akka.Persistence.Query" -> ["Akka.Persistence", preReleaseVersion; "Akka.Streams", release.NugetVersion]
| "Akka.Persistence.Query.Sql" -> ["Akka.Persistence.Query", preReleaseVersion; "Akka.Persistence.Sql.Common", preReleaseVersion]
| "Akka.Persistence.Sql.TestKit" -> ["Akka.Persistence.Query.Sql", preReleaseVersion; "Akka.Persistence.TestKit", preReleaseVersion; "Akka.Streams.TestKit", preReleaseVersion]
| "Akka.Persistence.Sql.TestKit" -> ["Akka.Persistence.Query.Sql", preReleaseVersion; "Akka.Persistence.TestKit", preReleaseVersion; "Akka.Streams.TestKit", release.NugetVersion]
| persistence when (persistence.Contains("Sql") && not (persistence.Equals("Akka.Persistence.Sql.Common"))) -> ["Akka.Persistence.Sql.Common", preReleaseVersion]
| persistence when (persistence.StartsWith("Akka.Persistence.")) -> ["Akka.Persistence", preReleaseVersion]
| "Akka.DI.TestKit" -> ["Akka.DI.Core", release.NugetVersion; "Akka.TestKit.Xunit2", release.NugetVersion]
Expand Down Expand Up @@ -731,4 +732,6 @@ Target "AllTests" DoNothing //used for Mono builds, due to Mono 4.0 bug with FAK
"RunTests" ==> "AllTests"
"MultiNodeTests" ==> "AllTests"

Target "RunTestsNetCore" DoNothing

RunTargetOrDefault "Help"
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ popd > /dev/null

mono $SCRIPT_PATH/src/.nuget/nuget.exe update -self

mono $SCRIPT_PATH/src/.nuget/nuget.exe install FAKE -OutputDirectory $SCRIPT_PATH/src/packages -ExcludeVersion -Version 4.16.1
mono $SCRIPT_PATH/src/.nuget/nuget.exe install FAKE -OutputDirectory $SCRIPT_PATH/src/packages -ExcludeVersion -Version 4.61.3

mono $SCRIPT_PATH/src/.nuget/nuget.exe install xunit.runner.console -OutputDirectory $SCRIPT_PATH/src/packages/FAKE -ExcludeVersion -Version 2.0.0
mono $SCRIPT_PATH/src/.nuget/nuget.exe install NUnit.Console -OutputDirectory $SCRIPT_PATH/src/packages/FAKE -ExcludeVersion -Version 3.2.1
Expand Down
9 changes: 9 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
###############
# folder #
###############
/**/DROP/
/**/TEMP/
/**/packages/
/**/bin/
/**/obj/
_site
4 changes: 4 additions & 0 deletions docs/api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
###############
# temp file #
###############
*.yml
1 change: 1 addition & 0 deletions docs/api/.manifest

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# PLACEHOLDER
TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*!
166 changes: 166 additions & 0 deletions docs/articles/actors/coordinated-shutdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
---
uid: coordinated-shutdown
title: Coordinated Shutdown
---
# Coordinated Shutdown
There's an `ActorSystem` extension called `CoordinatedShutdown` that will stop certain Akka.NET actors / services and execute tasks in a programmable order during shutdown.

The default phases and their orderings are defined in the default HOCON configuration as `akka.coordinated-shutdown.phases`, and they are defined below:

```
phases {
# The first pre-defined phase that applications can add tasks to.
# Note that more phases can be be added in the application's
# configuration by overriding this phase with an additional
# depends-on.
before-service-unbind {
}
# Stop accepting new incoming requests in for example HTTP.
service-unbind {
depends-on = [before-service-unbind]
}
# Wait for requests that are in progress to be completed.
service-requests-done {
depends-on = [service-unbind]
}
# Final shutdown of service endpoints.
service-stop {
depends-on = [service-requests-done]
}
# Phase for custom application tasks that are to be run
# after service shutdown and before cluster shutdown.
before-cluster-shutdown {
depends-on = [service-stop]
}
# Graceful shutdown of the Cluster Sharding regions.
cluster-sharding-shutdown-region {
timeout = 10 s
depends-on = [before-cluster-shutdown]
}
# Emit the leave command for the node that is shutting down.
cluster-leave {
depends-on = [cluster-sharding-shutdown-region]
}
# Shutdown cluster singletons
cluster-exiting {
timeout = 10 s
depends-on = [cluster-leave]
}
# Wait until exiting has been completed
cluster-exiting-done {
depends-on = [cluster-exiting]
}
# Shutdown the cluster extension
cluster-shutdown {
depends-on = [cluster-exiting-done]
}
# Phase for custom application tasks that are to be run
# after cluster shutdown and before ActorSystem termination.
before-actor-system-terminate {
depends-on = [cluster-shutdown]
}
# Last phase. See terminate-actor-system and exit-jvm above.
# Don't add phases that depends on this phase because the
# dispatcher and scheduler of the ActorSystem have been shutdown.
actor-system-terminate {
timeout = 10 s
depends-on = [before-actor-system-terminate]
}
}
```

## Custom Phases

As an end-user, you can register tasks to execute during any of these shutdown phases and add additional phases if you wish.

More phases can be added to an application by overriding the HOCON of an existing phase to include additional members in its `phase.depends-on` property. Here's an example where an additional phase might be executing before shutting down the cluster, for instance:

```
akka.coordinated-shutdown.phases.before-cluster-shutdown.depends-on = [service-stop, my-phase]
my-phase{
timeout = 10s
recover = on
}
```

For each phase, the following properties can be set:

1. `depends-on` - specifies which other phases have to run successfully first before this phase can begin;
2. `timeout` - specifies how long the tasks in this phase are allowed to run before timing out;
3. `recover` - if set to `off`, if any of the tasks in this phase throw an exception then the `CoordinatedShutdown` will be aborted and no further phases will be run. If set to `on` then any thrown errors are suppressed and the system will continue to execute the `CoordinatedShutdown`.

The default phases are defined in a linear order, but in practice the phases are ordered into a directed acyclic graph (DAG) using [Topological sort](https://en.wikipedia.org/wiki/Topological_sorting).

## Registering Tasks to a Phase

For instance, if you're using [Akka.Cluster](../clustering/cluster-overview) it's commonplace to register application-specific cleanup tasks during the `cluster-leave` and `cluster-exiting` phases. Here's an example:

```
var coordShutdown = CoordinatedShutdown.Get(myActorSystem);
coordShutdown.AddTask(CoordinatedShutdown.PhaseClusterLeave, "cleanup-my-api", () =>
{
return _myCustomSocketApi.CloseAsync().ContinueWith(tr => Done.Instance);
});
```

Each shutdown task added to a phase must specify a function that returns a value of type `Task<Done>`. This function will be invoked once the `CoordinatedShutdown.Run()` command is executed and the `Task<Done>` returned by the function will be completed in parallel with all other tasks executing in the given phase. Those tasks may complete in any possible order; `CoordinatedShutdown` doesn't attempt to order the execution of tasks within a single phase. Once all of those tasks have completed OR if the phases timeout has expired, the next phase will begin.

Tasks should be registered as early as possible, preferably at system startup, in order to ensure that all registered tasks are run. If tasks are added after the `CoordinatedShutdown` have begun its run, it's possible that the newly registered tasks will not be executed.

## Running `CoordinatedShutdown`
There are a few different ways to start the `CoordinatedShutdown` process.

If you wish to execute the `CoordinatedShutdown` yourself, you can simply call `CoordinatedShutdown.Run()`, which will return a `Task<Done>`.

```csharp
CoordinatedShutdown.Get(myActorSystem).Run();
```

It's safe to call this method multiple times as the shutdown process will only be run once and will return the same completion task each time. The `Task<Done>` will complete once all phases have run successfully, or a phase with `recover = off` failed.

### Automatic `ActorSystem` and Process Termination
By default, when the final phase of the `CoordinatedShutdown` executes the calling `ActorSystem` will be terminated. However, the CLR process will still be running even though the `ActorSystem` has been terminated.

If you'd like to automatically terminate the process running your `ActorSystem`, you can set the following HOCON value in your configuration:

```
akka.coordinated-shutdown.exit-clr = on
```

If this setting is enabled (it's disabled by default), you'll be able to shutdown the current running process automatically via an `Environment.Exit(0)` call made during the final phase of the `CoordinatedShutdown`.

### `CoordinatedShutdown` and Akka.Cluster
If you're using Akka.Cluster, the `CoordinatedShutdown` will automatically register tasks for completing the following:

1. Gracefully leaving the cluster;
2. Gracefully handing over / terminating ClusterSingleton and Cluster.Sharding instances; and
3. Terminating the `Cluster` system itself.

By default, this graceful leave action will by triggered whenever the `CoordinatedShutdown.Run()` method is called. Conversely, calling `Cluster.Leave` on a cluster member will also cause the `CoordinatedShutdown` to run and will terminate the `ActorSystem` once the node has left the cluster.

By default, `CoordinatedShutdown.Run()` will also be executed if a node is removed via `Cluster.Down` (non-graceful exit), but this can be disabled by changing the following Akka.Cluster HOCON setting:

```
akka.run-coordinated-shutdown-when-down = off
```

### Invoking `CoordinatedShutdown.Run()` on Process Exit
By default `CoordinatedShutdown.Run()` will be called whenever the current process attempts to exit (using the `AppDomain.ProcessExit` event hook) and this will give the `ActorSystem` and the underlying clustering tools an opportunity to cleanup gracefully before the process finishes exiting.

If you wish to disable this behavior, you can pass in the following HOCON configuration value:

```
akka.coordinated-shutdown.run-by-clr-shutdown-hook = off
```
139 changes: 139 additions & 0 deletions docs/articles/actors/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
uid: dependency-injection
title: Dependency injection
---
# Dependency Injection
If your actor has a constructor that takes parameters then those need
to be part of the `Props` as well, as described above. But there are cases when
a factory method must be used, for example when the actual constructor arguments
are determined by a dependency injection framework.

The basic functionality is provided by a `DependencyResolver` class,
that can create `Props` using the DI container.

```csharp
// Create your DI container of preference
var someContainer = ... ;

// Create the actor system
var system = ActorSystem.Create("MySystem");

// Create the dependency resolver for the actor system
IDependencyResolver resolver = new XyzDependencyResolver(someContainer, system);
```
When creating actorRefs straight off your ActorSystem instance, you can use the DI() Extension.

```csharp
// Create the Props using the DI extension on your ActorSystem instance
var worker1Ref = system.ActorOf(system.DI().Props<TypedWorker>(), "Worker1");
var worker2Ref = system.ActorOf(system.DI().Props<TypedWorker>(), "Worker2");
```

## Creating Child Actors using DI
When you want to create child actors from within your existing actors using
Dependency Injection you can use the Actor Content extension just like in
the following example.

```csharp
// For example in the PreStart...
protected override void PreStart()
{
var actorProps = Context.DI().Props<MyActor>()
.WithRouter(/* options here */);

var myActorRef = Context.ActorOf(actorProps, "myChildActor");
}
```

> [!INFO]
> There is currently still an extension method available for the actor Context. `Context.DI().ActorOf<>`. However this has been officially **deprecated** and will be removed in future versions.
##Notes

> [!WARNING]
> You might be tempted at times to use an `IndirectActorProducer`
which always returns the same instance, e.g. by using a static field. This is
not supported, as it goes against the meaning of an actor restart, which is
described here: [What Restarting Means](xref:supervision#what-restarting-means).

When using a dependency injection framework, there are a few things you have
to keep in mind.

When scoping actor type dependencies using your DI container, only
`TransientLifestyle` or `InstancePerDependency` like scopes are supported.
This is due to the fact that Akka explicitly manages the lifecycle of its
actors. So any scope which interferes with that is not supported.

This also means that when injecting dependencies into your actor, using a
Singleton or Transient scope is fine. But having that dependency scoped per
httpwebrequest for example won't work.

Techniques for dependency injection and integration with dependency injection
frameworks are described in more depth in the
[Using Akka with Dependency Injection](http://letitcrash.com/post/55958814293/akka-dependency-injection)
guideline.

----

Currently the following Akka.NET Dependency Injection plugins are available:

## AutoFac

In order to use this plugin, install the Nuget package with
`Install-Package Akka.DI.AutoFac`, then follow the instructions:

```csharp
// Create and build your container
var builder = new Autofac.ContainerBuilder();
builder.RegisterType<WorkerService>().As<IWorkerService>();
builder.RegisterType<TypedWorker>();
var container = builder.Build();

// Create the ActorSystem and Dependency Resolver
var system = ActorSystem.Create("MySystem");
var propsResolver = new AutoFacDependencyResolver(container, system);
```

## CastleWindsor

In order to use this plugin, install the Nuget package with
`Install-Package Akka.DI.CastleWindsor`, then follow the instructions:

```csharp
// Create and build your container
var container = new WindsorContainer();
container.Register(Component.For<IWorkerService>().ImplementedBy<WorkerService>());
container.Register(Component.For<TypedWorker>().Named("TypedWorker").LifestyleTransient());

// Create the ActorSystem and Dependency Resolver
var system = ActorSystem.Create("MySystem");
var propsResolver = new WindsorDependencyResolver(container, system);
```

## Ninject

In order to use this plugin, install the Nuget package with
`Install-Package Akka.DI.Ninject`, then follow the instructions:

```csharp
// Create and build your container
var container = new Ninject.StandardKernel();
container.Bind<TypedWorker>().To(typeof(TypedWorker));
container.Bind<IWorkerService>().To(typeof(WorkerService));

// Create the ActorSystem and Dependency Resolver
var system = ActorSystem.Create("MySystem");
var propsResolver = new NinjectDependencyResolver(container,system);
```

## Other frameworks

Support for additional dependency injection frameworks may be added in the
future, but you can easily implement your own by implementing an
[Actor Producer Extension](DI Core).






Loading

0 comments on commit 946dfdc

Please sign in to comment.