Rebus graceful shutdown

Viewed 233

I'm trying to perform a graceful shutdown with .NET Core 3.1 and Rebus however when I try to inject Rebus in the IHostedService it stops logging info.

My setup is as follows

internal class LifetimeEventsHostedService : IHostedService
    {
        private readonly ILoggingAdapter<LifetimeEventsHostedService> _logger;
        private readonly IHostApplicationLifetime _appLifetime;
        private readonly IBus _bus;

        public LifetimeEventsHostedService(
            ILoggingAdapter<LifetimeEventsHostedService> logger,
            IHostApplicationLifetime appLifetime,
            IBus bus)
        {
            _logger = logger;
            _appLifetime = appLifetime;
            _bus = bus;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _appLifetime.ApplicationStarted.Register(OnStarted);
            _appLifetime.ApplicationStopping.Register(OnStopping);
            _appLifetime.ApplicationStopped.Register(OnStopped);

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        private void OnStarted()
        {
            _logger.LogWarning(new LogItem { Message = "Application Started." });
        }

        private void OnStopping()
        {
            _logger.LogInformation(new LogItem { Message = "Application Stopping." });

            _bus.Advanced.Workers.SetNumberOfWorkers(0);
        }

        private void OnStopped()
        {
            _logger.LogInformation(new LogItem { Message = "Application Stopped." });
        }
    }

And then in my startup I have

services.AddHostedService<LifetimeEventsHostedService>();
1 Answers

When you use any of Rebus' IoC integration packages (Rebus.ServiceProvider, Rebus.CastleWindsor, Rebus.Autofac, etc.), it will automatically set itself up so that it is shut down gracefully, when the container is disposed.

So if you want the bus to shut down gracefully, simply ensure that the IoC container it's hosted in gets disposed, when your application shuts down.

This also holds for the built-in container adapter (which is not actually an IoC container, more like a handler factory of sorts) – simply do this (or something equivalent):

using (var activator = new BuiltinHandlerActivator())
{
    Configure.With(activator)
        .Transport(...)
        .(...)
        .Start();

    // bus is running now
}

// bus is stopped – all handlers have finished executing

and then the bus will shut down gracefully, stopping receive operations, giving all handlers up to 60 seconds (if I remember correctly) to finish whatever they're doing.

Related