Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep .NET Core console app alive in Docker container

I am testing a .NET Core 2.0 app which uses the Service Bus SDK to retrieve messages from an Event Hub. I setup a console app to do that, and intend to run the app as a Docker container.

This method creates the Event Host Processor which will read the messages:

    private static async Task MainAsync(string[] args)
    {
        Console.WriteLine("Registering EventProcessor...");

        var eventProcessorHost = new EventProcessorHost(
            EhEntityPath,
            PartitionReceiver.DefaultConsumerGroupName,
            EhConnectionString,
            StorageConnectionString,
            StorageContainerName);

        // Registers the Event Processor Host and starts receiving messages
        Console.WriteLine("Retrieving messages");
        await eventProcessorHost.RegisterEventProcessorAsync<EventProcessor>();

        Console.WriteLine("Sleeping");
        Thread.Sleep(Timeout.Infinite);
    }

As the event processor implemented in class EventProcessor will be the one handling the events, I am trying to prevent the console app to exit when the registration of the Processor is finished.

However, I can't find a reliable way to keep the app alive. If I run this container as-is, all I see in the output window is:

Registering EventProcessor...
Retrieving messages
Sleeping

and no messages are ever received.

like image 532
Luis Delgado Avatar asked Oct 21 '17 20:10

Luis Delgado


1 Answers

Thanks all for the suggestions.

I followed those articles but eventually ended up with this, which applies specifically to .NET Core apps:

https://github.com/aspnet/Hosting/issues/870

I've tested it and the app can shutdown gracefully when it receives a termination signal from the Docker runtime.

UPDATE: this is the relevant sample from the GH issue link above:

public class Program
{
    public static void Main(string[] args)
    {
        var ended = new ManualResetEventSlim();
        var starting = new ManualResetEventSlim();

        AssemblyLoadContext.Default.Unloading += ctx =>
        {
            System.Console.WriteLine("Unloding fired");
            starting.Set();
            System.Console.WriteLine("Waiting for completion");
            ended.Wait();
        };

        System.Console.WriteLine("Waiting for signals");
        starting.Wait();

        System.Console.WriteLine("Received signal gracefully shutting down");
        Thread.Sleep(5000);
        ended.Set();
    }
}
like image 154
Luis Delgado Avatar answered Mar 17 '23 23:03

Luis Delgado