2016-08-31

Azure AppService is my go-to when I want to create cloud-based applications. I have no desire to set up or administer a VM. Sometimes, though, you just need a service that quietly does its job in the background. That’s why I love WebJobs.

However, I found myself in the situation where I needed a WebJob that ran on a schedule, but could also be triggered manually. Oh, and depending on the environment I don’t want the schedule to run. Oh, and I have four environments. Oh, and I have five WebJobs.

Configuring 20 WebJob instances by hand isn’t the end of the world, but what happens when I want to add WebJobs? The approach doesn’t scale. I needed a way to manage some of this complexity through configuration, so I wrote a WebJobBase class that I can inherit from, which gives me almost everything I want for free.

I’ll begin by showing the entire instance. From there, I will describe each code block and its purpose.

WebJobBase.cs

Constructor

This is typical, minimal setup for a WebJob. The key thing to note here is passing in webJobName. This is important because it will determine names for our Service Bus topics, subscriptions, and it will be used by our NameResolver.

GetConfiguration

My app.config/web.config/Azure WebApp Application Settings contains a flag that determines if we ever even parse our TimerTriggers. This enables us to configure timers on a per-environment basis.

For my purposes, I want to be able to trigger a function via a Service Bus topic in all environments. This could easily be wrapped in a config flag similar to timers. We’ll dive into CreateStartSubscription in the next section.

Here, we setup our NameResolver. We’ll look at this in a bit.

We want to use the core WebJobs configuration options.

CreateStartSubscription

First, if you’re not familiar with Service Bus, Topics, or Subscriptions, I highly recommend you familiarize yourself before continuing: https://azure.microsoft.com/en-us/documentation/articles/service-bus-dotnet-how-to-use-topics-subscriptions/

Here, we create our manager to interact with Service Bus.

Next, we pull some Configuration Settings, and build our subscription name. This is the first place our WebJob name plays a role. We’re building a Topic subscription specific to this WebJob on this environment.

ServiceBusTopicResolver

Our ServiceBusTopicResolver is going to implement INameResolver. This is going to allow us to have configurable attributes in our WebJob functions. Like this:

Calling message.Complete() is important. Otherwise, the message will sit in the topic and trigger the function multiple times.

Specifically, notice the %WebJobsTopicName% and %SubscriptionName%. We can’t put ConfigurationManager.AppSettings[“ThisEnvironmentTopic”] in an attribute tag, so the name resolver keys off of the “%” to do the replacement for us.

This is the only potentially strange block. If we’re not specifically looking for a subscription name, we just get a general app setting. This could probably be refactored.

So, how do I run it?

All we need to do to trigger one of Service Bus functions, is put a message on the Topic. You can write a CLI/WPF/WinForms/Web app to do this. Personally, I’m a huge fan of LinqPad for little scripts like this. This is the one I wrote:

You can specify multiple WebJobs and environments, configure the BrokeredMessage, and hit F5.

So what does the actual WebJob look like?

Yep. That’s it. Everything else is in the actual functions to be triggered.

Conclusion

I’ve found this approach has solved about 90% of my challenges when managing WebJobs. My most common use cases are automatically included with new jobs, and I now have a common point to extend and improve ALL of my existing WebJobs.

This class is out in GitHub if you want to try it for yourself (https://github.com/DontPanicLabsBlog/WebJobBaseClass). If you do, let me know how it goes and how you’re using it.

The post Managing Azure WebJobs with Base Classes appeared first on Don't Panic Labs.

Show more