Start Azure Web Jobs On Demand

I've been working on an Azure based solution recently and have been using the free tiers to quickly get the solution up and running and to perform the first few QA cycles. The core solution is based around single app service website and then a second website that acts as the host for a continuous web job which is triggered via a queue. The problem with the free tiers is that there's a high possibility that the web job would shut itself down and hibernate if it is idle for more that 20 mins:

As of March 2014, web apps in Free mode can time out after 20 minutes if there are no requests to the scm (deployment) site and the web app's portal is not open in Azure. Requests to the actual site will not reset this.

A little research shows a few possible solutions:

  1. If the job is not time sensitive, then manually start the service remotely using a script or tool.
  2. Make your code explicitly start the web job just as a new request is being enqueued. This can be done by making a REST call to the deployment site.
  3. And lastly, upgrade to a basic or standard tier and enabling "Always On" keeps the site (and jobs) "warm" and prevent them from hibernating.

Using Powershell

This method requires the Microsoft Azure Powershell module to be installed on the machine. This can be installed via the Web Platform Installer.

  1. Start of by logging into the Azure account and registering your subscription

    Add-AzureAccount

  2. Next, starts the job:

    start-azurewebsitejob -name samplejobweb -jobname sample-execution-job -jobtype continuous

  3. And this command to stop the job:

    stop-azurewebsitejob -name samplejobweb -jobname sample-execution-job

Using REST / Code

I used this code as a template to whip up a console application that can be used to start the service:

static void Main(string[] args)
{
    string websiteName = "<website name>";
    string webjobName = "<job name>";
    string userName = "<publishing username>";
    string userPWD = "<publishing password>";
    string webjobUrl = string.Format("https://{0}.scm.azurewebsites.net/api/continuouswebjobs/{1}", websiteName, webjobName);

    var result = GetWebjobState(webjobUrl, userName, userPWD);
    Console.WriteLine(result);

    var postResult = StartWebjob(webjobUrl + "/Start", userName, userPWD);
    Console.WriteLine(postResult);

    Console.ReadKey(true);
}

private static JObject GetWebjobState(string url, string username, string password)
{
    var client = CreateHttpClient(username, password);
    var data = client.GetStringAsync(url).Result;
    var result = JsonConvert.DeserializeObject(data) as JObject;
    return result;
}

private static bool StartWebjob(string url, string username, string password)
{
    var client = CreateHttpClient(username, password);
    HttpResponseMessage data = client.PostAsync(url, new StringContent(string.Empty)).Result;
    return data.StatusCode == System.Net.HttpStatusCode.OK;
}

private static HttpClient CreateHttpClient(string username, string password)
{
    HttpClient client = new HttpClient();
    string auth = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ':' + password));
    client.DefaultRequestHeaders.Add("authorization", auth);
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    return client;
}

References

comments powered by Disqus