Tuesday 18 September 2018

An Azure Function to keep other Functions/URLs warmed up

imageJust a very quick post to share some code that might be useful. If you’re running Azure Functions on a consumption plan (i.e. pay for what you use), then you might know that a function app can go to sleep, leading to cold start issues. If it’s code you’re running behind a web part, PowerApp or other user-facing thing (usually on a HTTP trigger), then every now and then users will get really bad performance as they wait for the function app to spin back up again. Currently the timeout period for Azure Functions is 20 minutes – so if there are periods where your function won’t run, you’ll suffer from this issue.

As noted in Understanding serverless cold start and Azure Functions cold starts in numbers, just how long it takes to warm-up your function depends on many things. JavaScript functions can be slower than other languages if you’re using lots of npm modules for example.

You *could* switch to an App Service plan for your function. But then your costs will (typically) be much higher because you’re paying for dedicated VM instances in Azure, rather than taking advantage of one of the key advantages of serverless, in that you can pay for only the time your code is executing.

So, why not have another function which runs on a timer and just hits a series of URLs you specify in config?  This is a nice way of having one centralized function that can help out with *many* other functions distributed across many function apps on a consumption plan. So long as this code runs more frequently than the timeout period, you can be guaranteed that your other functions will be kept alive and performance will be good. Of course, there are numerous ways you could do this (a PowerShell script running somewhere, a Flow which executes on a schedule etc.) but if you like the idea of another function, then you can copy/paste my code below and get the solution implemented in minutes.

Here’s some code for a C# function to do this. You might want to take things further in terms of error-handling or something else, but it does the core job and might save you a quick coding/testing exercise - simply create a new C# function and use this as the implementation:

The code above expects an App Setting named “EndPointUrls” where the value contains a list of semi-colon separated URLs - your code will hit each of these:

SNAGHTMLe0b2fdb

You should then see a successful execution every 10 minutes (or whatever schedule you chose):

SNAGHTMLe01450a

NOTE – you should be able to run *this* function on a consumption plan too without any problems. I’ve seen issues with timer functions not running in some circumstances, but none should apply in this case. But look out for these in your other timer functions perhaps:

  • Functions which make async HTTP calls with HttpClient or similar, but are not async “all the way down”. To make use of this with “await”, you should change the signature of your Run() method to be:
  • Functions which run for longer than the schedule e.g. runs for 1 minute 20 seconds but is scheduled every minute. Of course you’ll miss executions!
    • NOTE – the myTimer.IsPastDue property show in my first log statement can help you understand if this execution is due to this
  • Functions being missed due to app restarts
    • You might want to consider what other things exist in the same Function App
  • Look at the “useMonitor” flag for frequently-running functions

Also see:

No comments: