Уведомление об остановке непрерывного веб-задания Azure для заданий типа NoAutomaticTrigger

Все,

Я переношу существующий код рабочей роли в веб-задание Azure. Я пытаюсь использовать SDK WebJob (1.0), чтобы обеспечить полную интеграцию с веб-сайтом Azure.

Сложно то, что JobHost плохо работает с заданиями, выходящими за рамки обычных параметров вызова на основе атрибутов (очереди, большие двоичные объекты и т. Д.)

У меня уже есть стандартный код, который я не могу изменить для прослушивания очередей / тем Azure и т. Д., Поэтому я не могу использовать код WebJob для этого.

Поэтому мне нужно использовать метод WebJob Call:

var cancelTokenSource = new CancellationTokenSource();
var onStartMethod = typeof(Program).GetMethod("OnStart", BindingFlags.Static | BindingFlags.Public);

host.CallAsync(onStartMethod, cancelTokenSource.Token)
    .ConfigureAwait(false)
    .GetAwaiter()
    .GetResult();

NB: Я использую свой собственный CallAsync, так как все рекомендации заключаются в использовании ConfigureAwait (false) при использовании библиотек, но внутренности JobHost этого не делают, поэтому я сам реплицирую этот код «вызова», но с ConfigureAwait. Насколько я могу судить, токен отмены ничего не делает в JobHost.

Моя проблема в том, что мне нужно вызвать host.RunAndBlock (); чтобы остановить выполнение задания, и это нормально, но затем мне нужно выполнить некоторую очистку. Я не могу сделать новый вызов CallAsync с помощью метода OnStop, так как Host уже отменяется, поэтому все, что я могу сделать, это сделать прямой вызов моего метода OnStop. К сожалению, тогда я теряю возможность писать в журнал веб-сайта через предоставленный класс TextWriter.

Я думаю, что мне нужно, чтобы JobHost мог вызвать мой метод в RunAndBlock, чтобы затем я мог забрать токен отмены, срабатывающий при выключении хоста, а затем выполнить свой код очистки .... но похоже, что это не так. любым способом сделать это.

Есть ли очевидный способ, которым я упускаю? JobHost действительно плохо справляется со сценариями, выходящими за рамки нормы :(


person GrahamB    schedule 04.01.2015    source источник


Ответы (2)


Как сказал победитель, вы можете использовать Microsoft.Azure.WebJobs.WebJobsShutdownWatcher
Это реализация решения Amit: Плавное выключение веб-заданий

Итак, я нашел решение для этого:
Никаких изменений в Program.cs

class Program
{
    static void Main()
    {
        var host = new JobHost();
        host.Call(typeof(Startup).GetMethod("Start"));
        host.RunAndBlock();
    }
}

плавное завершение работы идет в Startup.cs:

public class Startup
{
    [NoAutomaticTrigger]
    public static void Start(TextWriter log)
    {
        var token = new Microsoft.Azure.WebJobs.WebJobsShutdownWatcher().Token;
        //Shut down gracefully
        while (!token.IsCancellationRequested)
        {
            // Do somethings
        }
    }
}

После цикла while вы также можете останавливать запущенные задачи.

person Thomas    schedule 01.07.2015

NB: Я использую свой собственный CallAsync, так как все рекомендации заключаются в использовании ConfigureAwait (false) при использовании библиотек, но внутренности JobHost этого не делают, поэтому я сам реплицирую этот код «вызова», но с ConfigureAwait. Насколько я могу судить, токен отмены ничего не делает в JobHost.

Это ожидается, потому что вы передаете свой собственный токен отмены, который никем не отменяется. Токен отмены веб-заданий отменяется при отправке уведомления о завершении работы или хост остановлен / ликвидирован. Если вы хотите получить ссылку на токен отмены извне функции веб-задания, вы должны сохранить его в статической переменной или в чем-то подобном.

Если вы хотите использовать свой собственный токен отмены, вы можете использовать Microsoft.Azure.WebJobs.WebJobsShutdownWatcher для получения уведомления о завершении работы.

Моя проблема в том, что мне нужно вызвать host.RunAndBlock (); чтобы остановить выполнение задания, и это нормально, но затем мне нужно выполнить некоторую очистку. Я не могу сделать новый вызов CallAsync с помощью метода OnStop, так как Host уже отменяется, поэтому все, что я могу сделать, это сделать прямой вызов моего метода OnStop. К сожалению, тогда я теряю возможность писать в журнал веб-сайта через предоставленный класс TextWriter.

Для этого нет готового решения, но вы можете вызвать функцию очистки из запущенного веб-задания (если есть). Если вам нужна очистка вне функции, и вы также хотите вести журнал, вы можете только вести журнал в консоли - писать в console. Журналы будут отображаться на панели управления веб-заданиями на странице веб-заданий. Мне любопытно, если вам нужна очистка вне функции, каков сценарий?

person Victor Hurdugaci    schedule 06.01.2015
comment
Мой сценарий заключается в том, что в начале задания я подписываюсь на очереди / темы, используя собственный код адаптера для служебной шины Azure (т. Е. Я не могу использовать для этого встроенный механизм), затем мне нужно заблокировать ожидание появления сообщений , а затем, когда веб-задание остановлено, мне нужно перехватить это и вызвать мою логику отмены подписки. Мне трудно понять (а) как получить токен отмены, используемый WebJob при завершении работы (это нигде не отображается) или (б) перехватить завершение работы, поскольку нет события, которое я мог бы подключить . - person GrahamB; 07.01.2015
comment
Вы можете проверить, когда веб-задания останавливаются / перезапускаются, следуя коду blog .amitapple.com / post / 2014/05 / webjobs-graceful-shutdown. - person pranav rastogi; 19.01.2015