We are releasing another preview of the Microsoft Azure WebJobs SDK, which was introduced by Scott Hanselman. To read more about the previous preview, read this announcement post.
This release has the same general feature set as 0.4.0-beta as well as a few new exciting ones.
Download this release
You can download the WebJobs SDK from the NuGet gallery. You can install or update these packages from the NuGet gallery using the NuGet Package Manager Console, like this:
Install-Package Microsoft.Azure.WebJobs –Pre
If you want to use Microsoft Azure Service Bus triggers, install the following package:
Install-Package Microsoft.Azure.WebJobs.ServiceBus -Pre
What is the WebJobs SDK?
The WebJobs feature of Microsoft Azure Web Sites provides an easy way for you to run programs such as services or background tasks in a Web Site. You can upload and run an executable file such as an .exe, .cmd, or .bat file to your web site while running these as triggered or continuous WebJobs. Without the WebJobs SDK, connecting and running background task requires a lot of complex programming. The SDK provides a framework that lets you write a minimum amount of code to get common tasks done.
The WebJobs SDK has a binding and trigger system which works with Microsoft Azure Storage Blobs, Queues and Tables as well as Service Bus. The binding system makes it easy to write code that reads or writes Microsoft Azure Storage objects. The trigger system calls a function in your code whenever any new data is received in a queue or blob.
Updates in this preview
Only public functions defined in public classes will be indexed.
Starting with this release, the SDK will only look for public functions defined in public classes. If you have non-public functions or they are defined in a non-public class, the functions will not be indexed and the SDK will not be able to call those functions.
The following is a valid function definition:
public class Functions { public static void ProcessQueue([QueueTrigger("input")] string input) { } }
The following will not work because the containing class is not public:
class Functions { public static void ProcessQueue([QueueTrigger("input")] string input) { } }
Parallel execution with Queues
Support for async functions was added in the 0.4.0-beta release of the SDK. As part of that release the SDK added parallelism where functions listening on different queues could be triggered in parallel.
In this release, we added support for fetching messages for a queue in parallel within a QueueTrigger. This means if a function is listening on a queue as shown below, we will get a batch of 16 (default) queue messages in parallel for this queue. The function is also executed in parallel.
public class Program { static void Main() { JobHost host = new JobHost(); host.RunAndBlock(); } public static void ProcessQueue([QueueTrigger("input")] string input) { } }
The following code will add the same functionality that was there in 0.4.0-beta. You can configure the batch size with the JobHostConfiguration class as follows:
public class Program { static void Main() { JobHostConfiguration config = new JobHostConfiguration(); config.Queues.BatchSize= 1; JobHost host = new JobHost(config); host.RunAndBlock(); } }
BlobTriggers will be processed only once
In the previous releases BlobTriggers were always reprocessed until a newer Blob output existed. This meant that in some cases blobs would be reprocessed.
This release of the SDK ensures that BlobTrigger will only be processed when new blobs are detected or existing blobs are updated.
The following code shows how you can trigger a function when a blob is created or updated.
public class Program { static void Main() { JobHost host = new JobHost(); host.RunAndBlock(); } public static void ProcessBlob([BlobTrigger("test/{name}")] string input) { } }
These changes also allow to start a blob to queue based workflow when a BlobTrigger is processed. The following code shows how to write a queue message when a BlobTrigger is processed.
public class Program { static void Main() { JobHost host = new JobHost(); host.RunAndBlock(); } public static void BlobToQueue( [BlobTrigger("test/{name}")] string input,string name, [Queue("newblob")] out string message) { message = name; } }
The SDK will add a container called “azure-webjobs-hosts” to your Azure storage account (specified by AzureWebJobsStorage) where the SDK maintains
a blob receipt for each blob that it has processed and it uses this container to keep processing status of each blob.
The blob receipt has the following information for a particular Blob that was processed:
- What function was triggered for this Blob (FunctionId)
- container name
- blob type
- blob name
- ETag – version of the blob.
If you want to force reprocessing of a blob, then just delete the blob receipt for that particular blob from the “azure-webjobs-hosts” container.
The following image shows the “azure-webjobs-hosts” container, which shows the blob receipt for a blobs which was processed.
Retry and Error handling for Blobs
This release of the SDK adds support for retrying functions when there was an error processing a blob. A BlobTrigger will be processed up to a specified maximum number of retries (the default is 5 times).
When the threshold value is reached and the function is executed 5 times, the SDK will put a message in the queue called “webjobs-blobtrigger-poison”. You can trigger a function using QueueTrigger on this queue and do your custom error handling of the message. The queue message contains the following information as a JSON serialized string:
- FunctionId – Id of the function for which the blob was processed.
- BlobType – Type of Blob eg PageBlob or BlockBlob
- ContainerName of the blob
- BlobName
- ETag – version of the blob that caused a failure.
The following function shows how to handle error processing of blobs:
public class Program { static void Main() { JobHost host = new JobHost(); host.RunAndBlock(); } public static void ProcessBlob([BlobTrigger("test/{name}")] string input) { throw new Exception(); } public static void BlobErrorHandler( [QueueTrigger("webjobs-blobtrigger-poison")] BlobTriggerErrorMessage message) { } public class BlobTriggerErrorMessage { public string FunctionId { get; set; } public string BlobType { get; set; } public string ContainerName { get; set; } public string BlobName { get; set; } public string ETag { get; set; } } }
This sample also shows you how you can strongly type the queue message to a class called BlobTriggerPosionMessage since the message is a JSON-serialized string and the SDK allows you to bind a JSON serialized object to a POCO (Plain Old CLR Object).
The following code how you can configure the retry count for processing blobs. This is the same configuration object used to handle poison messages for a queue. This means this setting controls the retry count for retrying functions which are processing either blobs or queues.
public class Program { static void Main() { JobHostConfiguration config = new JobHostConfiguration(); config.Queues.MaxDequeueCount = 2; JobHost host = new JobHost(config); host.RunAndBlock(); } }
Samples
Samples for WebJobs SDK can be found at https://github.com/Azure/azure-webjobs-sdk-samples
- You can find samples on how to use triggers and bindings for blobs, tables, queues and Service Bus.
- There is a sample called PhluffyShuffy which is an Image processing Website where a customer can upload pictures which will trigger a function to process those pictures from blob storage.
Documentation
- Tutorial: Getting Started with the Windows Azure WebJobs SDK
- Channel 9 video on Making Your Jobs Easier With Windows Azure WebJobs SDK
- Introduction to WebJobs and SDK by Scott Hanselman
- A web site monitor built using WebJobs and ASP.NET by Brady Gaster
- Azure WebJobs – Recommended Resources
- WebJobs video series on Azure Friday
Deploying WebJobs with SDK to Azure Websites
Visual Studio 2013 Update 3 with Azure SDK 2.4 added Visual Studio Tooling support to publish WebJobs to Azure Websites. For more information, see How to Deploy Azure WebJobs to Azure Websites
Known Issues when migrating from 0.4.0-beta to 0.5.0-beta
Only public functions defined in public classes will be indexed.
Starting with this release the SDK will only look for public functions defined in a public class. If you had private functions or they were defined in a private class, the functions will not be indexed and the SDK will not be able to call those functions.
Give feedback and get help
The WebJobs feature of Microsoft Azure Web Sites and the Microsoft Azure WebJobs SDK are in preview. Any feedback to improve this experience is always welcome.
If you have questions that are not directly related to the tutorial, you can post them to the Azure forum, the ASP.NET forum, or StackOverflow.com. Use #AzureWebJobs SDK for Twitter and the tag Azure-WebJobsSDK for StackOverflow.