Docs: BackgroundService class running in Docker linux container

Created on 26 Jun 2018  Â·  12Comments  Â·  Source: dotnet/docs

I have an issue when running a BackgroundService in a Docker linux container. Is there any way to achieve a graceful shutdown? I am sending a docker container stop command and after a short pause the system shuts down without triggering a cancellation token. I need to have notice so I can try to prevent my long running process from shutting down mid-process. The UseShutdownTimeout also seems to have no effect. Any advice on how to get the graceful shutdown process working with docker?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

guide - .NET Microservices Area - .NET Architecture Guide product-question

All 12 comments

Maybe acting on System.Runtime.Loader.AssemblyLoadContext.Default.Unloading can fix your issue?

c# System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += ctx => { Stop("AssemblyLoadContext.Default.Unloading"); };

For a example see : https://github.com/WireMock-Net/WireMock.Net-docker/blob/master/StandAlone.NETCoreApp/Program.cs#L24

Hi @johnabbott72, I'm pinging @eiximenis, he might have some insights on this subject.

Hi @johnabbott72
Not sure if I understand your issue. I implemented a basic IHostedService using the instructions in https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice and it worked without problems:

image

If you share your HostedService code maybe could try to repro the issue!

Thanks @eiximenis,

If I understood it right, the key part here is starting the background tasks with a token from CancellationTokenSource, so processes can be signaled to terminate when the .Cancel() method is called from the BackgroundService.StopAsync().

And the BackgroundService.StopAsync() is called by the runtime, right?

@StefH, If I understood your code, it could be a way to call BackgroundService.StopAsync() upon app pool flushing on IIS, is that right?

I am getting this issue as well.
I have a hosted service that is reading messages from azure event hub, I run it in docker, however when i issue a docker stop, the stopasync does not get called and the cancellation token does not change to true.

@johnabbott72 have you found a fix for your issue?
@eiximenis Can you share your example? The only one i found is a web host but that is not my scenraio.

What information should I share to help? Its .net 3, my worker is inheriting from BackgroundService. I can see that StartAsync gets called.

This is my Main.cs:

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build() .Run();
}

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
                    .AddEnvironmentVariables().Build();
            })
            .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>();    });

}

Thanks for any assistance!

@eiximenis Any chance for some direction?

Many thanks!

Hi @johnabbott72, @amirxnz,

I created a very simple console app running the generic host with logging to trace the shutdown process in this repo: https://github.com/mvelosop/explore-hosted-services

The README in the repo should get you going.

You can explore shutting down the app from Windows and Docker.

In the sample I'm registering the services with:

services.AddSingleton<IHostedService, ServiceA>();

But services.AddHostedService<Worker>() should work as well.

Hope this helps.

@mvelosop thank you for your help,
So i have been working on this for the last couple of days, and now I'm actually thinking the problem may be caused by the visual studio docker run command?

Did you do anything to adjust how that command is run?

Thanks!

Hi @amirxnz,

Nope, well, actually I did it all from the command line, there's too much "magic" for me when running from VS.

There's one important detail to keep in mind if you're looking at logs. You have to make sure that logs are flushed on app shutdown, otherwise you might be loosing some events.

That's what the finally here is for:

try
{
    await builder.RunConsoleAsync();
}
finally
{
    Log.CloseAndFlush();
}

Hope this helps.

@mvelosop I guess that was my mistake because it makes no sense for visual studio to block the sigterm but apparently it does

Well, didn't now that either but it's good to know!

Glad you could solve this 😊

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stjepan picture stjepan  Â·  3Comments

svick picture svick  Â·  3Comments

skylerberg picture skylerberg  Â·  3Comments

sebagomez picture sebagomez  Â·  3Comments

garfbradaz picture garfbradaz  Â·  3Comments