Azure Function and WebJob - strange behavior when timer-triggered

1k views Asked by At

I am experimenting with two .NET Framework-based mechanisms on Azure that can be timer-triggered: Azure Function v1 and WebJob. AF is deployed on Function App and WebJob is deployed on Api App. Both have Free plan set.

I was hoping that running some test code (1 line in console) repeatedly by having a CRON schedule (testing both with: "0 */10 * * * *" which is once every 10 minutes) will be an easy task. It doesn't appear so.

Note: before starting the experiment I already knew from testing a queue-triggered WebJob that a continuous WebJob should be set to 'Always on' to prevent sleeping after an hour or so. But this cannot be enabled on Free and Shared plans. However, on a queue-triggered WebJob I managed to create a workaround by sending an authenticated request to the app to wake it up every time I add a new message to the queue, this way I ensure that the WebJob is not sleeping when it has some work to be done i.e. a queue message to process.

However I thought that timer-triggered WebJob should not be "Continuous" but rather a "Triggered" one. But when I deploy it as a "Triggered" one then I get this error:

(Inner Exception #0) ExitCode: -1, Output: Command 'cmd /c ""HeartbeatW ...' was aborted due to no output nor CPU activity for 121 seconds. You can increase the SCM_COMMAND_IDLE_TIMEOUT app setting (or WEBJOBS_IDLE_TIMEOUT if this is a WebJob) if needed.

I'm not sure how increasing timeout could help with this and to which value it should be set, but maybe there's something wrong with my Main code:

static void Main()
{
    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddTimers();
    });
    builder.ConfigureLogging((context, b) =>
    {
        b.AddConsole();

    });
    var host = builder.Build();
    using (host)
    {
        host.Run();
    }
}

Deploying the WebJob as "Continuous" instead of "Triggered" prevents this error but there are still 2 issues:

  • after the deployment I need to go to the portal and select "Run" to make the WebJob start - I haven't found if this can be automated or do I have to switch to a paid plan
  • the WebJob goes to sleep after an hour or so after running (because it's running on a Free plan and cannot be set as "Always on") and I don't have a workaround this time to wake it up because there is no manual operation involved

Going further to Azure Function, it gets worse. If I deploy my Function, wait some time and go to Function > Monitor I can see that the Function didn't run on the time slots when it was supposed to. However, if I keep the Monitor view open then I can see that the Function has now started to run according to schedule! So I guess viewing the logs triggers the Function to wake up the same as sending an authenticated request to the app does to the WebJob. At least it does it for an hour or so because after that the Function logs do not show new runs.

I've read that both Azure Function and WebJob run on the same scheduler under the hood. It is the cause of this behavior of Azure Function?

Are all of these by design and cannot be changed? Or should I make some adjustments in the deployment process?

1

There are 1 answers

0
Doris Lv On

Your case is not normal in Portal. Since I'm not sure about your project, let's do the job step by step again.


WebJob sdk on .NET Framework 4.7.2.

  1. Create a Console app based on .net framework 4.7.2 in Visual Studio. enter image description here

  2. Paste you code to Program.cs. Add Azure Storage connection for Azure WebJob Sdk.

     static async Task Main()
     {
         var builder = new HostBuilder();
         builder.ConfigureWebJobs(b =>
         {
             b.AddAzureStorageCoreServices();
             b.AddAzureStorage();
             b.AddTimers();
         });
         builder.ConfigureLogging((context, b) =>
         {
             b.AddConsole();
         });
         var host = builder.Build();
         using (host)
         {
             await host.RunAsync();
         }
     }
    
  3. Test it locally, found no job function. enter image description here

  4. Add function in the project: right click your project-> Add-> New Items-> Class.cs->Rename it to Function. Here is a function run every minute.

     public static void ProcessTimerTrigger([TimerTrigger("0 * * * * *")] TimerInfo myTimer, ILogger logger)
             {
                 logger.LogInformation("Message from Class1.");
             }
    
  5. Install the package required. Here are some webjob packages and version I use:

     <package id="Microsoft.Azure.WebJobs" version="3.0.23" targetFramework="net472" />
     <package id="Microsoft.Azure.WebJobs.Extensions" version="4.0.1" targetFramework="net472" />
     <package id="Microsoft.Azure.WebJobs.Extensions.Storage" version="4.0.3" targetFramework="net472" />
     <package id="Microsoft.Azure.WebJobs.Host.Storage" version="4.0.1" targetFramework="net472" />
     <package id="Microsoft.Extensions.Hosting" version="5.0.0" targetFramework="net472" />
     <package id="Microsoft.Extensions.Logging" version="5.0.0" targetFramework="net472" />
     <package id="Microsoft.Extensions.Logging.Console" version="5.0.0" targetFramework="net472" />
    
  6. Configure appsettings.json for Azure Storage connection.

     {
       "ConnectionStrings": {
         "AzureWebJobsStorage": "YourStorageConnectionString;"
       }
     }
    
  7. Run locally. Successfully. enter image description here


  1. Deploy as WebJob to Portal. Successfully. enter image description here

  1. For Function, it is running even you don't open log. You can check in many places, such as metrics, kudu log files (https://yourapp.scm.azurewebsites.net/DebugConsole-> LogFiles-> Application-> Functions-> Function-> YourFunctionName-> file).

By the way, when publish console app as WebJob, choose run continuously.

Reference: Get started with the Azure WebJobs SDK for timer-trigger background processing