Getting work done in the cloud - on time

TL;DR: When using Azure Functions to get tasks executed daily, weekly, monthly or on a schedule, here is a few things you need to know. First off, the function needs to run on a Basic plan or bigger (more expensive). The Shared or Free plans does not allow the "always on" option that is need in classic mode. If you select something bigger than the Basic plan, you can run the function in "dynamic" mode, which means you'll only pay for the time it uses to execute.


The problem(s)

In my quest to move all the sites and applications I run from old shared hosting on a physical server (or virtual), to cloud hosting, I'm forcing myself to rethink some of the decisions I've made when I created the solutions.

Like many developers, I've used ASP.NET to execute scheduled task and run asynchronous and long running tasks, even though it's not exactly what it was meant for. There's even a couple of libraries out there to help developers do it.

I have a site that has a feed with news from some manufacturers. This feed is updated daily. When I first moved the site to a Web Role, that's what it was called back then, the task was handled by calling a Web Api action at 3 AM every day using a scheduler job collection (another Azure feature). This task wasn't exactly finish in a few seconds, it downloads web pages from several manufacturer websites and scans the html to find any new products announced since last time we visited.

So this job eats a fair amount of memory and certainly steal CPU cycles. And this is going on in a web application, where we probably have several requests/threads coming in all the time. Apart from when waiting for replies to Http requests, this task would be better off not having to share the CPU with other threads. And then there's the whole 3 AM thing. Looking at the visitor logs from the site, there's not really any good time for hitting it with this amount of work, at least not without slowing the site down for other visitors.

A last point, I had to include code for making these Http requests and parsing the returned Html. This code is only used for that one task. I like to keep things simple,

Azure Functions to the rescue.

Azure Functions is a serverless event driven experience that extends the existing Azure App Service platform. These nano-services can scale based on demand and you pay only for the resources you consume.

The solution

Go to the Azure portal, and click 'New' in the menu to the left or just press the 'N' key on the keyboard. Then select 'Compute', and in the new pane that opens up, you'll find the 'Function App'. Click that.

Now we're presented with a few options, and be careful, this is where you might make it hard on yourself. If you're not sure what it is you're doing, you might end in the same situation I ended in, and get a time triggered function that doesn't trigger.

So here's a few hints.

  • If you want something that is running on some sort af schedule, and get's triggered by a timer, you need a function that is not using a 'Free plan'. So no freebies here! So select the 'Classic' app service plan and go with a Basic or Standard plan here, and remember to turn on "always on". This also lets you (or forces you) to control scaling etc. yourself.
  • Or if you want to only pay for what you use, you should select the 'Dynamic' app service plan.
Classic vs Dynamic plan

Classic vs Dynamic plan

So by following the reply to my StackOverflow question (above), I ended up selecting a 'Dynamic' plan. I'll keep you posten on what this ends up costing. With the dynamic plan, it's hard to predict what the price will be, as you get the resource you need (CPU and RAM), and the price is calculated based on how many seconds you functions runs, and how much RAM it uses.

With the 'Classic' plan you get full control over how much it costs, as you select a App Service, just like a web site, and you're going to pay for that based on what plan you select for that. And you need to select 'Always on', so if you need it to run around the clock, you'll end up paying by the month, the price given by the plan you selected.

And finally, some code.

First off, the function.json file I use:

{
  "bindings": [
    {
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 0 3 * * *",
      "name": "myTimer"
    }
  ],
  "disabled": false
}

This make the function run every day at 3 AM.

And then the function, written in C# script. I'll just post the signature of the function, the code is irrelevant for this post. The method does not have to be async, so if you don't need that, just remove async and replace Task with void.

public static async Task Run(TimerInfo myTimer, TraceWriter log) {
    // Lot's of code go here!
}

Comments

Thank you for your comment! If it's not spam, it will be published shortly!

Your e-mail address will not be published. Required fields are market *

*

Copyright © 2015-2016 by Steen F. Tøttrup. Powered by NBlogEngine by creativeminds & Romangie Theme.