Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Graceful Shutdown from Dotnet Core 2.0 app

I have a .NET Core 2.0 console app running in a local Docker Linux container (Docker CE 18.03.1 stable channel) and am trying to handle a graceful shutdown.

My app has handlers for both AppDomain.CurrentDomain.ProcessExit and AssemblyLoadContext.Default.Unloading:

        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        AssemblyLoadContext.Default.Unloading += Default_Unloading;

The handlers simply write log messages when called.

I find that, when I do a docker stop <containerid>, neither handler is called and after a short delay. The container simply stops running. I've tried debugging the app in Visual Studio and have tried running without the debugger. In all cases, the handlers aren't getting called.

Is there some other magic incantation that I'm missing?

like image 718
Mr. T Avatar asked Jun 01 '18 15:06

Mr. T


2 Answers

I cannot reproduce this behaviour.

This is the code I used in a console app:

    private static readonly AutoResetEvent _closing = new AutoResetEvent(false);

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        AssemblyLoadContext.Default.Unloading += Default_Unloading;

        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Console.WriteLine(DateTime.Now.ToString());
                Thread.Sleep(1000);
            }
        });
        Console.CancelKeyPress += new ConsoleCancelEventHandler(OnExit);
        _closing.WaitOne();
    }

    private static void Default_Unloading(AssemblyLoadContext obj)
    {
        Console.WriteLine("unload");
    }

    private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
    {
        Console.WriteLine("process exit");
    }

    protected static void OnExit(object sender, ConsoleCancelEventArgs args)
    {
        Console.WriteLine("Exit");
        _closing.Set();
    }

With this docker file:

FROM microsoft/dotnet:2.0-sdk
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy and build everything else
COPY . ./
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "out/shutdown.dll"]

This is the output: (with docker stop <id>)

06/01/2018 16:31:16
06/01/2018 16:31:17
06/01/2018 16:31:18
unload
process exit

I'm using Docker for Windows with a Linux container.

like image 189
Mathias Avatar answered Sep 26 '22 12:09

Mathias


Very strange behavior.
I was having the same issue and for me it turned out that it does NOT work when I use the following entrypoint in the dockerfile:

ENTRYPOINT dotnet DockerTest.dll

When I change it to the following, it works:

ENTRYPOINT ["dotnet", "DockerTest.dll"]

I hope this helps :)

like image 40
Simon Mattes Avatar answered Sep 26 '22 12:09

Simon Mattes