Creating functionality in Azure to subscribe to messages on a queue is so 2013. You have to set up a service bus, learn about queues, topics, maybe subscribers and filters, blah, BLAH, BLAH.
Let’s not forget configuring builds and deployments and all that.
Fun though this may be, what if you want to have just the equivalent of a cronjob or scheduled task kicking off every few hours or days for some long-running or CPU-intensive task
Scheduled tasks – Old School: IaaS
Well, sure, you could create a VM, log in, and configure cron/scheduled tasks. However, all the cool kids are using webjobs instead these days. Get with the programme, grandpa! (Or something)
So what’s a webjob when it’s at home?
It depends. Each version is the equivalent of a small console app that lives in the ether (i.e., on some company’s server in a rainy field in Ireland), but how it kicks off the main functionality is different.
These webjobs can be deployed as part of a website, or ftp-ed into a specific directory; we’ll get onto this a bit later. Once there, you have an extra dashboard available which gives you a breakdown of the job execution history.
It uses the Microsoft.WindowsAzure.Jobs assemblies and can be best installed via nuget:
Install-Package Microsoft.WindowsAzure.Jobs.Host -Pre
(Notice the “-Pre”: this item is not fully cooked yet. It might need a few more months before you can safely eat it without fear of intestinal infrastructure blowout)
Let’s check out the guts of that assembly shall we?
We’ll get onto these attributes momentarily; essentially, these allow you to decorate a public method for the job host to pick up and execute when the correct event occurs.
Here’s how the method will be called:
Notice that all of the other demos around at the moment not only use RunAndBlock, but they don’t even use the CancellationToken version (if you have a long running process, stopping it becomes a lot easier if you’re able to expose a cancellation token to another – perhaps UI – thread).
Setting it up
Right now you have limited options for deploying a webjob.
For each option you firstly need to create a new Website. Then click the WebJobs (Preview) tab at the top. Click Add at the bottom.
Now it gets Old Skool.
Zip
Zip the contents of your app’s bin/debug folder, call it WebJob.zip (I don’t actually know if the name matters though).
Enter the name for your job and browse to the zip file to upload.
You can choose; run continuously, run on a schedule (if you have Azure Scheduler Preview enabled), and run on demand.
There’s a great article on asp.net covering this method.
FTP
Webjobs are automagically picked up via convention from a particular directory structure. As such, you can choose to ftp (or other deployment method, perhaps via WebDeploy within the hosting website itself, a git commit hook, or a build server) the files that would have been in the zip into:
site\wwwroot\App_Data\jobs\{job type}\{job name}
What I’ve discovered doing this is that the scheduled jobs are in fact actually triggered jobs, which means that they are actually triggered via an HTTP POST from the Azure Scheduler.
There’s a nice intro to this over on Amit Apple’s blog
When to execute
Remember those attributes?
Storage Queue
One version can be configured to monitor a Storage Queue (NOT a service bus queue, as I found out after writing an entire application to do this, deploy it, then click around the portal for an entire morning, certain I was missing a checkbox somewhere).
By using the attribute [QueueInput] (and optionally [QueueOutput]) your method can be configured to automatically monitor a Storage Queue, and execute when the appropriate queue has something on it.
Blob
A method with the attribute [BlobInput] (and optionally [BlobOutput]) will kick off when a blob storage container has something uploaded into it.
Woah there!
Yep, that’s right. Just by using a reference to an assembly and a couple of attributes you can shortcut the entire palava of configuring azure connections to a namespace, a container, creating a block blob reference, and/or a queue client, etc; it’s just there.
Crazy, huh?
On Demand
When you upload your webjob you are assigned a POST endpoint to that job; this allows you to either click a button in the Azure dashboard to execute the method, or alternatively execute it via an HTTP POST using Basic Auth (automatically configured at the point of upload and available within the WebJobs tab of your website).
You’ll need a [NoAutomaticTrigger] or [Description] attribute on this one.
Scheduled
If you successfully manage to sign up for the Azure Scheduler Preview then you will have an extra option in your Azure menu:
Where you can even add a new schedule:
This isn’t going to add a new WebJob, just a new schedule; however adding a new scheduled webjob will create one of these implicitly.
In terms of attributes, it’s the same as On Demand.
How to execute
Remember those methods?
RunAndBlock
These require the Main method of your non-console app to instantiate a JobHost and “runandblock”. The job host will find a matching method with key attribute decorations and depending on the attributes used will fire the method when certain events occur.
[csharp]
static void Main()
{
JobHost h = new JobHost();
h.RunAndBlock();
}
public static void MyAwesomeWebJobMethod(
[BlobInput("in/{name}")] Stream input,
[BlobOutput("out/{name}")] Stream output)
{
// A new cat picture! Resize all the things!
}
[/csharp]
Scott Hanselman has a great example of this.
Call
Using some basic reflection you can look at the class itself (in my case it’s called “Program”) and get a reference to the method you want to call such that each execution just calls that method and stops.
[csharp]
static void Main()
{
var host = new JobHost();
host.Call(typeof(Program).GetMethod("MyAwesomeWebJobMethod"));
}
[NoAutomaticTrigger]
public static void MyAwesomeWebJobMethod()
{
// go find epic cat pictures and send for lulz.
}
[/csharp]
I needed to add in that [NoAutomaticTrigger] attribute, otherwise the webjob would fail completely due to no valid method existing.
In summary
WebJobs are fantastic for those offline, possibly long running tasks that you’d rather not have to worry about implementing in a website or a cloud service worker role.
I plan to use them for various small functions; at Mailcloud we already use a couple to send the sign-ups for the past few days to email and hipchat each morning.
Have a go with the non-scheduled jobs, but if you get the chance to use Azure Scheduler it’s pretty cool!
Good luck!
References
- http://www.windowsazure.com/en-us/services/scheduler/
- http://curah.microsoft.com/52143/using-the-webjobs-feature-of-windows-azure-web-sites
- http://www.windowsazure.com/en-us/documentation/articles/web-sites-create-web-jobs/
- http://blog.amitapple.com/post/74215124623/deploy-azure-webjobs/
- http://www.hanselman.com/blog/IntroducingWindowsAzureWebJobs.aspx
- http://www.asp.net/aspnet/overview/developing-apps-with-windows-azure/getting-started-with-windows-azure-webjobs