11

As per my understanding Azure function will execute

In case RunOnStartup = true

   1. on startup 
   2. if a host changed 
   3. a new deployment happen
   4. on schedule time

And, In case RunOnStartup = false or not define

   1. on schedule time only

but when I am running it locally with RunOnStartup = false, it is executing on startup as well and on azure portal it is working fine. Can anyone please suggest why it happen?

update:- Function code:-

    public static void Run([TimerTrigger("0 30 3 * * *", RunOnStartup = false)]TimerInfo myTimer, TraceWriter log, ExecutionContext executionContext)
    {
        log.Info($"Function1- Timer trigger function executed at: {DateTime.Now}");
        try
        {
            //main work
        }
        catch (Exception ex)
        {
            log.Error(ex.Message, ex);
        }
        finally
        {
            log.Info($"Function1 - Timer trigger function ENDED at: {DateTime.Now}");
        }
    }

Console output:-

   your worker runtime is not set. As of 2.0.1-beta.26 a worker runtime setting is

required. Please run func settings add FUNCTIONS_WORKER_RUNTIME <option> or add FUNCTION S_WORKER_RUNTIME to your local.settings.json Available options: dotnet, node, python

              %%%%%%
             %%%%%%
        @   %%%%%%    @
      @@   %%%%%%      @@
   @@@    %%%%%%%%%%%    @@@
 @@      %%%%%%%%%%        @@
   @@         %%%%       @@
     @@      %%%       @@
       @@    %%      @@
            %%
            %

  Azure Functions Core Tools (2.3.148 Commit hash:     f9b3db04f9833b431f1b001efb3e5783a169ebfc)
  Function Runtime Version: 2.0.12210.0
  [19-Dec-18 8:22:47 AM] Building host: startup suppressed:False, configuration suppressed: False
  [19-Dec-18 8:22:47 AM] Reading host configuration file 'D:\path****\host.json'
  [19-Dec-18 8:22:47 AM] Host configuration file read:
  [19-Dec-18 8:22:47 AM] {
  [19-Dec-18 8:22:47 AM]   "version": "2.0"
  [19-Dec-18 8:22:47 AM] }
  [19-Dec-18 8:22:47 AM] Initializing Host.
  [19-Dec-18 8:22:47 AM] Host initialization: ConsecutiveErrors=0, StartupCount=1
  [19-Dec-18 8:22:47 AM] Starting JobHost
  [19-Dec-18 8:22:47 AM] Starting Host (HostId=boldsombirk-85417686, InstanceId=4f41b83d-022e-4e75-b75b-528890f62058, Version=2.0.12210.0, ProcessId=7012, AppDomainId=1, InDebugMode=False, InDiagnosticMode=False, FunctionsExtensionVersion=)
  [19-Dec-18 8:22:47 AM] Loading functions metadata
  [19-Dec-18 8:22:48 AM] 1 functions loaded
  [19-Dec-18 8:22:48 AM] Generating 1 job function(s)
  [19-Dec-18 8:22:48 AM] Found the following functions:
  [19-Dec-18 8:22:48 AM] Function1.Run
  [19-Dec-18 8:22:48 AM]
  [19-Dec-18 8:22:48 AM] Host initialized (673ms)
  [19-Dec-18 8:22:49 AM] Executing 'Function1' (Reason='Timer fired at 2018-12-19T13:52:49.5718606+05:30', Id=e1603f8f-41d0-492e-8674-d5771813422d)
  [19-Dec-18 8:23:41 AM] Function1 - Timer trigger function executed at: 19-Dec-18 1:53:41 PM
Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
Sombir Kumar
  • 1,841
  • 1
  • 17
  • 30
  • Please add some more relevant information like source code and configuration. With the current information, we can't help you. One specific question: when you startup the Function locally, it tells you what its next runtimes will be. Could you post that information/the console output too? – rickvdbosch Dec 19 '18 at 08:09
  • If you have any confusion about my explanation, just ask. If it does help could you accept it for more people to refer? – Jerry Liu Jan 18 '19 at 04:01

2 Answers2

10

Let's start with an example, a timer trigger starts with 0 */5 * * * * schedule at 12/19/2018 4:01:00 PM, and we can see the schedule print

12/19/2018 4:05:00 PM
12/19/2018 4:10:00 PM
12/19/2018 4:15:00 PM
12/19/2018 4:20:00 PM
12/19/2018 4:25:00 PM

However, we stop(debugging) the project at 4:02 PM. And then run it again at 4:08 PM, we can see timer trigger execute on startup.

This happens because the ScheduleStatus(as below) has been stored in blob storage the first time the trigger starts. When we run the project again, timer trigger reads existing Next scheduled time and compares it with current time. If the scheduled Next moment has passed, timer trigger executes immediately on startup.

 // I am in UTC+8:00 time zone
{
    "Last":"0001-01-01T00:00:00",
    "Next":"2018-12-19T16:05:00+08:00",
    "LastUpdated":"2018-12-19T16:02:12.7071566+08:00"
}

Follow the sample in doc to handle execution for outdated schedule. The IsPastDue property is true when the current function invocation is later than scheduled.

[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
    if(myTimer.IsPastDue)
    {
        log.LogInformation("Timer is running late!");
    }
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
  • Thanks so much, this makes the behavior pretty clear. To avoid it, though, is it as easy as moving the "Next" time to the next planned execution rather than allowing a past due execution? – Blue Apr 11 '23 at 19:01
  • 1
    @Blue "moving the 'Next' time to next planned execution", I am not sure it's a good idea because the timer info is supposed to be completely handled by function runtime. Why not just leave the function do nothing if (myTimer.isPastDue == true)? – Jerry Liu Apr 12 '23 at 09:20
1

Jerry's answer is the correct one, but if you want quick fix when testing code with RunOnStartup then you can just change current Timer trigger to time in future.

Example : In your case change it from 0 30 3 * * * to 0 30 23 * * *.

Note : This is not a recommended practice. Outdated schedule must be handled.

Vivek Jain
  • 2,730
  • 6
  • 12
  • 27