2
votes

I'm trying to gracefully handle webjob shutdown in my functions. I'm using v3 of the Azure Webjobs SDK and the Service Bus Extensions.

Here is a test function I've written, based on some sample code here: https://github.com/Azure/azure-webjobs-sdk-samples/blob/master/BasicSamples/MiscOperations/Functions.cs

    public async Task ProcessQueueMessageAsync([ServiceBusTrigger("testqueue")] Message message, CancellationToken cancellationToken, ILogger logWriter)
    {
        logWriter.LogError("GOT MESSAGE");
        while (!cancellationToken.IsCancellationRequested)
        {
            await Task.Delay(2000);
            logWriter.LogError("Not Cancelled");
        }

        logWriter.LogError("CANCELLED!!!");           
    }

When I shut down the webjob, though, the cancellation doesn't get logged.

I've also tried catching a TaskCanceledException as shown in this example: https://github.com/mathewc/samples/blob/master/WebJobSamples/ContinuousJobGracefulShutdown/Functions.cs

That didn't work for me either. Any ideas how to implement this in my function?

UPDATE (12/18/18):

While I still haven't figured this out, I've got a workaround that suits my purposes. In my Program class, I'm declaring a public static CancellationToken shutdownToken variable, and setting it in my Main method to

shutdownToken = new WebJobsShutdownWatcher().Token;

Then I'm registering a callback in my function as follows:

Program.shutdownToken.Register(() => logWriter.LogWarning("Webjob is shutting down!"));
1

1 Answers

0
votes

I refer to your link code and write a WebJob with QueueTrigger, then upload it and stop it after it has run a while. My output log shows it works fine. Maybe you can refer to it.

public static string ShutDownFilePath
    {
        get
        {
            return shutDownFile;
        }
    }

    public static void ShutdownMonitorJob(
         [QueueTrigger("myqueue")] string message,
         TextWriter log,
         CancellationToken cancellationToken)
    {

        new Thread(new ThreadStart(() =>
        {
            log.WriteLine("From thread: In about 10 seconds, the job will be signaled to stop");
            Thread.Sleep(10000);

            // Modify the shutdown file
            File.WriteAllText(shutDownFile, string.Empty);
        })).Start();

        log.WriteLine("From function: Received a message: " + message);

        while (!cancellationToken.IsCancellationRequested)
        {
            log.WriteLine("From function: Cancelled: No");
            Thread.Sleep(2000);
        }

        // Perform the graceful shutdown logic here
        log.WriteLine("From function: Cancelled: Yes");
    }

And this is my output log.The cancelled status is changed to yes.

[12/18/2018 02:14:07 > dd4ec8: INFO] From function: Cancelled: No
[12/18/2018 02:14:07 > dd4ec8: INFO] From function: Cancelled: No
[12/18/2018 02:14:07 > dd4ec8: INFO] info: Function[0]
[12/18/2018 02:14:07 > dd4ec8: INFO]       From function: Cancelled: No
[12/18/2018 02:14:07 > dd4ec8: INFO]       
[12/18/2018 02:14:09 > dd4ec8: INFO] From function: Cancelled: No
[12/18/2018 02:14:09 > dd4ec8: INFO] From function: Cancelled: No
[12/18/2018 02:14:09 > dd4ec8: INFO] info: Function[0]
[12/18/2018 02:14:09 > dd4ec8: INFO]       From function: Cancelled: No
[12/18/2018 02:14:09 > dd4ec8: INFO]       
[12/18/2018 02:14:09 > dd4ec8: SYS INFO] Detected WebJob file/s were updated, 
refreshing 
WebJob
[12/18/2018 02:14:10 > dd4ec8: SYS INFO] Status changed to Stopping
[12/18/2018 02:14:11 > dd4ec8: INFO] From function: Cancelled: Yes
[12/18/2018 02:14:11 > dd4ec8: INFO] From function: Cancelled: Yes
[12/18/2018 02:14:11 > dd4ec8: INFO] info: Function[0]
[12/18/2018 02:14:11 > dd4ec8: INFO]       From function: Cancelled: Yes
[12/18/2018 02:14:11 > dd4ec8: INFO]       
[12/18/2018 02:14:11 > dd4ec8: INFO] Executed 'Functions.ShutdownMonitorJob' 
(Succeeded, Id=9ce21c43-c113-4794-b565-81cb615a29ab)
[12/18/2018 02:14:11 > dd4ec8: INFO] info: Host.Results[0]
[12/18/2018 02:14:11 > dd4ec8: INFO]       Executed 'Functions.ShutdownMonitorJob' 
(Succeeded, Id=9ce21c43-c113-4794-b565-81cb615a29ab)
[12/18/2018 02:14:11 > dd4ec8: INFO] Job host stopped

I did more test with ServiceBus Trigger.

Here is my Program.cs content.

static void Main(string[] args)
    {

        JobHostConfiguration config = new JobHostConfiguration();
        config.UseServiceBus();
        JobHost host = new JobHost(config);
        host.RunAndBlock();

    }

And here is my Function content.

private static string shutDownFile = Path.GetTempFileName();

    public static string ShutDownFilePath
    {
        get
        {
            return shutDownFile;
        }
    }


    public static void ShutdownMonitorJob(
         [ServiceBusTrigger("myqueue")]
         string myQueueItem,
         TextWriter log,
         CancellationToken cancellationToken)
    {

        new Thread(new ThreadStart(() =>
        {
            log.WriteLine("From thread: In about 10 seconds, the job will be signaled to stop");
            Thread.Sleep(10000);

            // Modify the shutdown file
            File.WriteAllText(shutDownFile, string.Empty);
        })).Start();

        log.WriteLine("From function: Received a message: " + myQueueItem);

        while (!cancellationToken.IsCancellationRequested)
        {
            log.WriteLine("From function: Cancelled: No");
            Thread.Sleep(2000);
        }

        // Perform the graceful shutdown logic here
        log.WriteLine("From function: Cancelled: Yes");
    }

}

And this my new log pic.enter image description here

I stopped the webjob and the status change normally.