[Preview] Web Jobs en Windows Azure Web sites

Ayer estuve revisando una nueva característica, aún en preview, para Windows Azure Web sites llamada Web Jobs. Gracias a ella, seremos capaces de lanzar procesos en segundo plano, ya sea manual o automáticamente.
Hace unas semanas vimos Scheduler (también en preview) y, si bien es cierto que la idea se aproxima, debemos ser conscientes de que no se trata exactamente de lo mismo, aunque cabe mencionar que estos web jobs se apoyan justamente en este otro servicio para su modo recurrente.

El job

Para trabajar con este servicio, debemos adjuntar un ejecutable que cumpla con uno de los siguientes tipos:

  • .cmd, .bat, .exe (windows cmd)
  • .sh (bash)
  • .php (php)
  • .py (python)
  • .js (node)

En mi caso, he creado una aplicación de consola:

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Configuration;
using System.Diagnostics;
using System.Linq;

namespace WebJobStorage
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime boundary = DateTime.Now.AddDays(-15);

            var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageAccount"].ConnectionString);
            var blobClient = storageAccount.CreateCloudBlobClient();

            var container = blobClient.GetContainerReference("stuff");

            var blobs = container.ListBlobs(useFlatBlobListing: true).OfType<CloudBlockBlob>();

            foreach (var blob in blobs)
            {
                if (blob.Properties.LastModified < boundary)
                {
                    Console.WriteLine("Warning: {0} is old", blob.Uri);
                }
            }

        }
    }
}

La única operación que realizo en este código es marcar un límite de 15 días, accedo a una cuenta de Windows Azure Storage y dentro de la misma a un contenedor llamado stuff. Busco dentro del mismo para recuperar todos los blobs y, por cada uno de ellos, compruebo cuál lleva sin modificarse más de 15 días. En este ejemplo sólo se mostrará por consola un mensaje de tipo Warning con la Uri del elemento en cuestión.

He compilado este código en modo Release y he comprimido todo el contenido de la carpeta que se genera en un .zip. Ahora lo que necesito es crear un web job que ejecute este código por mi.

Web Jobs en el portal

Una vez que tenemos el proceso que queremos lanzar, accedemos al portal de Windows Azure y seleccionamos el web site al que queremos asociar el job. En él veremos que existe un nuevo apartado llamado Web Jobs PREVIEW:

Web Jobs section WA Web Sites

Hacemos clic en la acción ADD A NEW JOB o en el botón ADD, en la parte inferior de la pantalla. Aparecerá el siguiente cuadro de diálogo:

Basic web job settings

  • NAME: Nombre del job. El mismo no puede contener ningún carácter especial, a excepción de – y _.
  • CONTENT (ZIP FILES – 200MB MAX): Localizamos el archivo .zip que generamos en el paso anterior y lo adjuntamos.
  • HOW TO RUN: Por último, debemos establecer de qué forma se ejecuta este proceso. A día de hoy existen tres opciones: Que siempre se esté ejecutando, programada (haciendo uso del servicio Scheduler mencionado anteriormente) o bajo demanda.

En este ejemplo he creado uno llamado jobstorage que será lanzado bajo demanda.

jobstorage-run-once on demand

En la imagen anterior se muestra lo que podemos ver una vez creado el job. En la parte inferior de la pantalla, cuando estamos posicionados sobre el elemento, nos permite ejecutarlo bajo demanda las veces que necesitemos. En la tabla podemos ver el estado del mismo, el tipo de ejecución que tiene, cuándo fue la última vez que se lanzó, el resultado de la última operación y, por último, un enlace al log de job. Si hacemos clic sobre él, accederemos a un segundo sitio donde podremos descargar el archivo de registro de cada una de las ejecuciones:

Triggered job history for jobstorage

El contenido de cualquiera de ellos es similar al siguiente:

Output Web Job

Como podemos observar, aparece información propia del servicio y, además, una línea por cada uno de los elementos que no cumple con el límite establecido en mi aplicación de consola.

Espero que haya sido de utilidad.

¡Saludos!