Изящная обработка задачи остановки AWS ECS с помощью .NET Core Application - PullRequest
0 голосов
/ 14 декабря 2018

Я написал консольное приложение ядра .NET для запуска в качестве задачи в AWS ECS Fargate.По сути, консольное приложение запускает поток обработки, а затем ему просто нужно продолжать работу (так же, как веб-хост Kestrel.)

Сначала я вставляю Console.ReadKey (), думая, что оно никогда не попадет, и приложениепродолжит бежать.Что ж, это приводит к исключению .NET ...

Cannot read keys when either application does not have a console 
or when console input has been redirected. Try Console.Read.

Поэтому я заменяю ReadKey на Console.Read ().Приложение работает так, как будто его даже нет, продолжает двигаться, и приложение закрывается, как только оно запускается.

В ходе исследований я обнаружил событие Console.CancelKeyPress.Я реализую это, и это работает в том факте, что консольное приложение будет продолжать работать.

ManualResetEvent _quitEvent = new ManualResetEvent(false);
Console.CancelKeyPress += (sender, eArgs) => {
                Console.WriteLine("Shutting down.");
                _quitEvent.Set();
                eArgs.Cancel = true;
            };
_quitEvent.WaitOne();

Но я хотел бы изящно обработать завершение работы приложения, когда это произойдет.

ЧерезВ ходе дополнительного исследования я обнаружил, что когда AWS ECS останавливает задачу, он не отправляет Ctrl-C (SIGINT), а вместо этого отправляет SIGTERM.https://docs.aws.amazon.com/cli/latest/reference/ecs/stop-task.html

Затем я реализую стандартную обработку событий для SIGTERM в .NET (см. Ниже).

AssemblyLoadContext.Default.Unloading += ctx =>
            {
                Console.WriteLine("Shutting down.");
                _quitEvent.Set();
            };
_quitEvent.WaitOne();

Это компилируется и нормально работает в ECS.НО ... Я нажал кнопку "Стоп" через консоль AWS ECS, она останавливает задачу и перезапускает новую задачу.Когда я просматриваю журнал этой остановленной задачи, там нет сообщения журнала выключения, никаких признаков постепенного выключения, ничего.Похоже, что его просто убили силой.

Я что-то здесь упустил?Что я могу сделать по-другому, чтобы изящно перехватить стоп-задачу в AWS ECS и изящно завершить задачу?

1 Ответ

0 голосов
/ 22 декабря 2018

Похоже, это связано с вашим .net-кодом обработки изящного завершения работы.Я только что протестировал со следующим кодом локально, с докером и с ECS Stop-Task.Во всех местах я получил изящное отключение.У меня нет вашего полного кода, поэтому я создал свой собственный пример.

using System;
using System.Runtime.Loader;
using System.Threading;

namespace consoleapp
{
    class Program
    {
        static void Main(string[] args)
        {
            var _quitEvent = new ManualResetEvent(false);
            AssemblyLoadContext.Default.Unloading += ctx =>
            {
                System.Console.WriteLine("Unloding fired");
                _quitEvent.Set();
            };
            System.Console.WriteLine("Waiting for signals");
            _quitEvent.WaitOne();
            System.Console.WriteLine("Received signal gracefully shutting down");
            Console.WriteLine("Hello World!");
        }
    }
}

Полная ссылка на репозиторий github, если вы хотите попробовать самостоятельно.https://github.com/imran9m/netconsoleapp.git

Примеры журналов, которые вы должны увидеть для контейнера.

Ожидание сигналов

Разблокировка сработала

Полученный сигнал изящно завершает работу

Hello World!

Примечание. - Для локального тестирования сигнала SIGTERM вам потребуется запустить kill -SIGTERM {PID} вместо CTRL + C в CLI dotnet.

...