-
Notifications
You must be signed in to change notification settings - Fork 17
make AkkaHostedService public
+ virtual
#306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Akka.Actor; | ||
using Akka.Annotations; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
|
@@ -11,36 +12,42 @@ namespace Akka.Hosting | |
/// <summary> | ||
/// INTERNAL API | ||
/// </summary> | ||
internal sealed class AkkaHostedService : IHostedService | ||
/// <remarks> | ||
/// Open for modification in cases where users need fine-grained control over <see cref="Actor.ActorSystem"/> startup and | ||
/// DI - however, extend at your own risk. Look at the Akka.Hosting source code for ideas on how to extend this. | ||
/// </remarks> | ||
[InternalApi] | ||
// ReSharper disable once ClassWithVirtualMembersNeverInherited.Global | ||
public class AkkaHostedService : IHostedService | ||
{ | ||
private ActorSystem? _actorSystem; | ||
private CoordinatedShutdown? _coordinatedShutdown; // grab a reference to CoordinatedShutdown early | ||
private readonly IServiceProvider _serviceProvider; | ||
private readonly AkkaConfigurationBuilder _configurationBuilder; | ||
private readonly IHostApplicationLifetime? _hostApplicationLifetime; | ||
private readonly ILogger<AkkaHostedService> _logger; | ||
protected ActorSystem? ActorSystem; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Made all of these accessible in derivative classes. |
||
protected CoordinatedShutdown? CoordinatedShutdown; // grab a reference to CoordinatedShutdown early | ||
protected readonly IServiceProvider ServiceProvider; | ||
protected readonly AkkaConfigurationBuilder ConfigurationBuilder; | ||
protected readonly IHostApplicationLifetime? HostApplicationLifetime; | ||
protected readonly ILogger<AkkaHostedService> Logger; | ||
|
||
public AkkaHostedService(AkkaConfigurationBuilder configurationBuilder, IServiceProvider serviceProvider, | ||
ILogger<AkkaHostedService> logger, IHostApplicationLifetime? applicationLifetime) | ||
{ | ||
_configurationBuilder = configurationBuilder; | ||
_hostApplicationLifetime = applicationLifetime; | ||
_serviceProvider = serviceProvider; | ||
_logger = logger; | ||
ConfigurationBuilder = configurationBuilder; | ||
HostApplicationLifetime = applicationLifetime; | ||
ServiceProvider = serviceProvider; | ||
Logger = logger; | ||
} | ||
|
||
public async Task StartAsync(CancellationToken cancellationToken) | ||
public virtual async Task StartAsync(CancellationToken cancellationToken) | ||
{ | ||
try | ||
{ | ||
_actorSystem = _serviceProvider.GetRequiredService<ActorSystem>(); | ||
_coordinatedShutdown = CoordinatedShutdown.Get(_actorSystem); | ||
await _configurationBuilder.StartAsync(_actorSystem); | ||
ActorSystem = ServiceProvider.GetRequiredService<ActorSystem>(); | ||
CoordinatedShutdown = CoordinatedShutdown.Get(ActorSystem); | ||
await ConfigurationBuilder.StartAsync(ActorSystem); | ||
|
||
async Task TerminationHook() | ||
{ | ||
await _actorSystem.WhenTerminated.ConfigureAwait(false); | ||
_hostApplicationLifetime?.StopApplication(); | ||
await ActorSystem.WhenTerminated.ConfigureAwait(false); | ||
HostApplicationLifetime?.StopApplication(); | ||
} | ||
|
||
// terminate the application if the Sys is terminated first | ||
|
@@ -51,22 +58,22 @@ async Task TerminationHook() | |
} | ||
catch (Exception ex) | ||
{ | ||
_logger.Log(LogLevel.Critical, ex, "Unable to start AkkaHostedService - shutting down application"); | ||
_hostApplicationLifetime?.StopApplication(); | ||
Logger.Log(LogLevel.Critical, ex, "Unable to start AkkaHostedService - shutting down application"); | ||
HostApplicationLifetime?.StopApplication(); | ||
} | ||
} | ||
|
||
public async Task StopAsync(CancellationToken cancellationToken) | ||
public virtual async Task StopAsync(CancellationToken cancellationToken) | ||
{ | ||
// ActorSystem may have failed to start - skip shutdown sequence if that's the case | ||
// so error message doesn't get conflated. | ||
if (_coordinatedShutdown == null) | ||
if (CoordinatedShutdown == null) | ||
{ | ||
return; | ||
} | ||
|
||
// run full CoordinatedShutdown on the Sys | ||
await _coordinatedShutdown.Run(CoordinatedShutdown.ClrExitReason.Instance) | ||
await CoordinatedShutdown.Run(CoordinatedShutdown.ClrExitReason.Instance) | ||
.ConfigureAwait(false); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,11 @@ public static IServiceCollection AddAkka(this IServiceCollection services, strin | |
/// and manages its lifecycle in accordance with Akka.NET best practices. | ||
/// </remarks> | ||
public static IServiceCollection AddAkka(this IServiceCollection services, string actorSystemName, Action<AkkaConfigurationBuilder, IServiceProvider> builder) | ||
{ | ||
return AddAkka<AkkaHostedService>(services, actorSystemName, builder); | ||
} | ||
|
||
public static IServiceCollection AddAkka<T>(this IServiceCollection services, string actorSystemName, Action<AkkaConfigurationBuilder, IServiceProvider> builder) where T:AkkaHostedService | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the generic code is identical to the non-generic one, we should just call the generic one from inside the non-generic extension method. Saves us the time to have to check that both implementation are the same in the future. |
||
{ | ||
var b = new AkkaConfigurationBuilder(services, actorSystemName); | ||
services.AddSingleton<AkkaConfigurationBuilder>(sp => | ||
|
@@ -72,7 +77,7 @@ public static IServiceCollection AddAkka(this IServiceCollection services, strin | |
else | ||
{ | ||
// start the IHostedService which will run Akka.NET | ||
services.AddHostedService<AkkaHostedService>(); | ||
services.AddHostedService<T>(); | ||
} | ||
|
||
return services; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning to users: there will be tears if you don't study our source code when you try to extend this, and we will not help you with whatever weird DI stuff you're trying to do. Best of luck.