Akka.NET Headless Service
Headless Actor
using Akka.Actor;
namespace AkkaHeadlesssService
{
internal class HeadlessActor : ReceiveActor
{
// Things that are possible with this actor:
// Connect to an Apache Kafka, Apache Pulsar, RabbitMQ instance or send/receive messages to/from a remote actor!
public HeadlessActor()
{
}
public static Props Prop()
{
return Props.Create<HeadlessActor>();
}
}
}
Headless Service
using Akka.Actor;
using Akka.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace AkkaHeadlesssService
{
public sealed class AkkaService : IHostedService
{
private IActorRef _actorRef;
private ActorSystem _actorSystem;
private readonly IServiceProvider _serviceProvider;
private readonly IHostApplicationLifetime _applicationLifetime;
public AkkaService(IServiceProvider sp, IHostApplicationLifetime applicationLifetime)
{
_serviceProvider = sp;
_applicationLifetime = applicationLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
var bootstrap = BootstrapSetup.Create();
// enable DI support inside this ActorSystem, if needed
var diSetup = DependencyResolverSetup.Create(_serviceProvider);
// merge this setup (and any others) together into ActorSystemSetup
var actorSystemSetup = bootstrap.And(diSetup);
// start ActorSystem
_actorSystem = ActorSystem.Create("headless-service", actorSystemSetup);
_actorRef = _actorSystem.ActorOf(HeadlessActor.Prop());
// add a continuation task that will guarantee shutdown of application if ActorSystem terminates
_actorSystem.WhenTerminated.ContinueWith(_ => {
_applicationLifetime.StopApplication();
});
return Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
// strictly speaking this may not be necessary - terminating the ActorSystem would also work
// but this call guarantees that the shutdown of the cluster is graceful regardless
await CoordinatedShutdown.Get(_actorSystem).Run(CoordinatedShutdown.ClrExitReason.Instance);
}
}
}
Headless Service Host
// See https://aka.ms/new-console-template for more information
using AkkaHeadlesssService;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureServices((_, services) =>
{
services.AddLogging();
services.AddHostedService<AkkaService>();
})
.ConfigureLogging((_, configLogging) =>
{
configLogging.AddConsole();
})
.UseConsoleLifetime()
.Build();
await host.RunAsync();
What About Windows Service?
Well, quickly, we have a sample application, Windows Service, to show how Windows Services
are now being built with BackgroundService
!