Azure WebJobs & .NET Core
I recently started a transition to utilising Azure for hosting at work, it was a triumphant moment when we all agreed that we could leverage some of the simpler and easier to maintain PAAS Azure offerings.
One of the first questions that came from the team was “How do we move our traditional background processes when we don’t have virtual machines to rely on?” A quick Google (or should I say Bing?) search later came up with Azure WebJobs.
WebJobs is a feature of Azure App Service that enables you to run a program or script in the same context as a web app, API app, or mobile app.
Azure WebJobs seemed perfect to run a scheduled task every 5/15/30/90 minutes (A Triggered WebJob) or to run an executable continuously (A continuous WebJob), for the the rest of the post I’ll be referring to continuous WebJobs using the Azure WebJob SDK. I’m using Version 3 which is still in beta, this allowed me to utilise .NET Core and seamlessly develop on my MacBook. (No virtual machine for me thank you very much!)
I started by bootstrapping a .NET Core Console Application and installing the Azure WebJobs SDK and Azure WebJobs Extensions, at the time of writing this post 3.0.0-beta5 was the latest available version.
dotnet new console -n azure-webjobs-sample
dotnet add package Microsoft.Azure.WebJobs -v 3.0.0-beta5
dotnet add package Microsoft.Azure.WebJobs.Extensions -v 3.0.0-beta5
The Azure WebJobs Extensions package, in my opinion, made development that little quicker. For example theres an extension to fire code every 30 seconds (Timer Extension), listen to an Queue on a Azure Service Bus, or even an extension to integrate with SendGrid.
To get started I needed to fulfil the following prerequisites
- An Azure Storage Account for WebJob Storage
- An Azure Storage Account for Dashboard Storage
Thankfully both of these can use the same storage account, I followed the quick start guide here Microsoft Azure Storage Quick Start Guide. Once complete I retrieved the storage keys Caveat: There’s some best practice guidelines here around key security, I’d recommend a quick search to make sure you’re doing it correctly.
I then setup up the Console Application with the following code, this came from multiple quick starts on the internet
public class Program
{
private const string StorageAccountConnectionString = "STORAGE_CONNECTION_STRING_HERE";
private const string DashboardConnectionString = "STORAGE_CONNECTION_STRING_HERE";
static void Main(string[] args)
{
var config = new JobHostConfiguration
{
DashboardConnectionString = DashboardConnectionString,
StorageConnectionString = StorageAccountConnectionString
};
config.UseTimers();
var host = new JobHost(config);
host.RunAndBlock();
}
}
All pretty simple, setup the Job Host so the SDK knows what storage accounts it should use, setup any extensions (Timers in my case) and then the run command (Line 17)
Finally, I created a functions folder and a newly created “Function” – basically a bit of code that will actually do the heavy lifting for us with the help from the WebJobs SDK.
public class SampleTimerFunction
{
public static void CronJob([TimerTrigger("*/20 * * * * *")] TimerInfo timerInfo)
{
Console.WriteLine("Timer fired!");
}
}
As you can see this method will execute automatically every 20 seconds, following usual (but confusing – I always have to look it up) CRON syntax. Whilst I’m just writing to the debug console here, it would be just as easy to:
- Write a cleanup script that runs hourly that moves your application logs, although I appreciate most of us are using a little more advanced logging strategy
- Send a lolcat to your whole development team every morning.
As I mentioned earlier, More extensions are available, most of them are still under beta to work with .NET Core, but the future is exciting! Check out the Azure WebJobs SDK Extension GitHub repo here: https://github.com/Azure/azure-webjobs-sdk-extensions
Finally the finished output of my super awesome console application, just a note, I know there are a lot of warnings in the output, this is the SDK handling background exceptions (Queue doesn’t exist because no shutdown message has been sent for example) See here for a more detailed explanation: https://github.com/Azure/azure-webjobs-sdk/issues/1483
Sample code can be found on GitHub: https://github.com/DanHorrocksBurgess/azure-webjobs-sample/