0

I am running an existing c# .net app as a triggered(OnDemand, not Continuous with queues/triggers/functions) webjob. Sometimes it is long running, like 30+ minutes. Works great.

[Edited] If I try to stop the webjob, by setting WEBJOBS_STOPPED to 1 in the Application Settings of my App Services, then the webjob will be Aborted by Azure/Kudu if it does not gracefully detect the shutdown and terminate itself in time (5 seconds? 30 seconds?)

I have tried using WebJobsShutdownWatcher() as several examples illustrate, and as Joey indicated, but it STILL does not detect the shutdown, and Azure/Kudu aborts it anyway. I have even manually coded the checking for the existence of the shutdown file (see WebJobsShutdownWatcher() code in GitHub), but that file does not appear to be created for my triggered/OnDemand webjob, so my code detects nothing.

My original question was: Does WebJobsShutdownWatcher() work for Triggered(OnDemand) webjobs? Or only for Continuous webjobs? I suspected WebJobsShutdownWatcher only works for Continuous webjobs, so I wanted to ask here before I spend more time trying to debug it.

I thought that Joey's answer worked, but I fooled myself because it appeared that the console app terminated because of the shutdown, but I now think it terminated because I had not coded it correctly. Anyway, even with the .Register() or checking .Token.IsCancellationRequested, my console app does not appear to get notified, so Azure/Kudu aborts it once I set WEBJOBS_STOPPED to 1.

So I am beginning to think perhaps there is other Azure code I must add to my simple console app, I dunno, like like JobHost initialization, and host.RunAndBlock(), or something like that, for Azure to do it's thing and fire the anonymous function I register with .Register, or set the .Token.IsCancellationRequested flag.

I have included my entire simple test program, all suggestions welcome, though I will say I'm hoping for minimal changes to my vanilla .NET console app, I don't really WANT to create any more stuff than I have to, like JobHost(), or have triggered functions that I have to configure in Azure to fire. Just a simple console app, with a settings.job with a cron schedule, that runs and stops, runs and stops, and if it detects a webjob shutdown, terminates early to avoid the Azure/Kudu Abort.

class Program
{
    static Boolean runFlag1 = true;
    static Boolean runFlag2 = true;
    static void Main(string[] args)
    {
        var watcher = new WebJobsShutdownWatcher();
        var cancellationToken = watcher.Token;
        cancellationToken.Register(() =>
        {
            Console.WriteLine("Webjob Shutdown signaled.");
            runFlag1 = false;
        });

        var t = Task.Run(() =>
        {
            Console.WriteLine("Beginning webjob loop...");
            while (runFlag1 && runFlag2)
            {
                Thread.Sleep(1000);
                Thread.Yield();

                if (watcher.Token.IsCancellationRequested)
                {
                    Console.WriteLine("");
                    Console.WriteLine("Webjob IsCancellationRequested=true");
                    runFlag2 = false;
                }
            }
            Console.WriteLine("");
            Console.WriteLine("Ending webjob loop, runFlag1={0} runFlag2={1}", runFlag1, runFlag2);
        });
        t.Wait();

        Console.WriteLine("Exited Task. runFlag1={0} runFlag2={1}", runFlag1, runFlag2);
    }
}

Thanks, Bo

Bo A
  • 138
  • 9

1 Answers1

0

Yes, you can use the WebJobsShutdownWatcher class while it has a Register function that is called when the cancellation token is canceled, in other words when the webjob is stopping.

var cancellationToken = new WebJobsShutdownWatcher().Token;
cancellationToken.Register(() =>
{
    Console.Out.WriteLine("Do whatever you want before the webjob is stopped...");
});

If you use Triggered functions, you can add a CancellationToken parameter to your function signatures. The runtime will cancel that token when the host is shutting down automatically, allowing your function to receive the notification. Here is a thread you could refer to.

public static void QueueFunction(
        [QueueTrigger("QueueName")] string message,
        CancellationToken cancellationToken)
{
    if(cancellationToken.IsCancellationRequested) return;
    ...
}
Joey Cai
  • 18,968
  • 1
  • 20
  • 30
  • Joey's answer is correct, the .Register function does work to fire when cancellation is happening for a webjob. My problem is that I was running a vanilla console app, with no JobHost, or Task.Run that seems to be necessary for the WebJobsShutdownWatcher() to do it's thing. Once I added that, then the WebJobsShutdownWatcher() did in fact fire the .Register function, or simply set the watcher.Token.IsCancellationRequested boolean to true, either method which works to help you detect shutdown and terminate your console app gracefully. – Bo A Jul 18 '19 at 03:16
  • Updated my question to clarify my configuration and continued problem properly detecting and shutting down to avoid an Azure/Kudu Abort. I thought Joey's answer was correct, and it may be if I implement it correctly, but I still seem to be missing something. – Bo A Jul 18 '19 at 17:43