Windows Azure : Créer simplement un scheduler

WinAzure_rgb_Blue286_SDans de nombreux projets, il est souvent nécessaire d’avoir sur Windows Azure un système de tâches planifiées qui soient récurrentes. Que ce soit par exemple pour une tâche quotidienne de purge, ou des notifications quotidiennes à ses utilisateurs. A ce jour, la plateforme est très limitée dans ce domaine, puisque il n’y a pas de scheduler sur Windows Azure autres que des addons ou des briques très récentes. Il est possible de passer par des systèmes extérieurs, mais c’est toujours une contrainte supplémentaire et le plus souvent une ligne de plus à ajouter sur la facture. Je vais donc vous présenter une manière simple et efficace de créer un scheduler sur Windows Azure, en se basant sur un système de Queue et de Worker Role, et bien entendu, il est scalable !

Pour information, ne vous inquiétez pas, la solution est sur Git et il y a un aussi un joli package NuGet.

Des solutions existantes…

Comme je l’ai précisé, il existe actuellement des solutions pour réaliser des schedulers sur Windows Azure. La première est de détourner le système pour utiliser celui de Windows Azure Mobile Services afin qu’il appelle des services web comme s’il s’agissait d’une tâche planifiée. Et oui, ce n’est pas prévu pour être utilisé de la sorte de base, mais comme c’est possible, c’est que c’est permis !

La deuxième solution serait d’utiliser les WebJobs de Windows Azure WebSites, une toute nouvelle fonctionnalité qui permet d’avoir des CRON via Windows Azure Websites. Celle-ci se base sur un dossier zippé qui contient un fichier pour lancer notre traitement de façon schedulée. Actuellement il n’y a pas d’API pour les gérer, mais on peut faire confiance à l’équipe Azure pour nous sortir cela, comme sur le reste de la plateforme.

La troisième solution serait d’utiliser le scheduler disponible dans les Addons de Windows Azure. Celui-ci a été développé par la société Aditi et il est de très bonne facture. Cependant il s’agit d’un service extérieur à notre abonnement Windows Azure. Le problème c’est que si l’on souhaite exécuter des jobs trop régulièrement, donc en dehors de la tranche gratuite, le scheduler change tout de suite de prix…

La quatrième solution est l’utilisation d’un scheduler totalement externe à Windows Azure. Pour ma part, j’ai testé SetCronJob qui fait clairement le travail malgré son interface très épurée… Mais même chose que le précédent, il vous faudra sûrement sortir la carte bleue une fois de plus.

La cinquième solution est bien entendu de le faire soit même. J’ai donc regardé ce qu’internet me propose et la plupart du temps, on nous conseille d’utiliser la librairie Quartz.Net. C’est une très bonne librairie pour tout ce qui est scheduler mais qui se base sur SQL Azure. Or je n’utilise pas toujours des bases relationnelles dans mes projets, donc en créer une uniquement pour cela me gène particulièrement. Si vous voulez plus d’informations sur Quartz.net, Alexandre Brisebois a écrit un super article sur le sujet que je vous conseille de lire.

Et la dernière solution, c’est d’utiliser la toute nouvelle API Windows Azure Scheduler dont vous pouvez retrouver toute la documentation sur MSDN : http://www.windowsazure.com/en-us/services/scheduler/. Pour moi c’est la solution la plus complète à ce jour et en plus c’est l’officielle ! Je la trouve encore un peu lourde à mettre en place mais rappelons que ce n’est qu’une première version qui est actuellement en preview.

Pour ma part, j’ai donc développé une autre solution.

Ma version du scheduler

Je suis parti du fait qu’il me faut un scheduler qui réponde aux critères suivants :

  • Scalable
  • Exécuter des jobs toutes les minutes / heures / jours
  • Multi actions
  • Simple à réutiliser

Bref des critères somme toute classiques pour un scheduler, mais je voulais avant tout qu’il soit simple à mettre en place et à réutiliser.

Un petit historique

Alors pourquoi avoir créé ce scheduler ? Tout simplement parce que j’utilise un système de scheduling dans la plupart de mes projets, que ça aille d’un simple agrégateur de RSS à la gestion d’actions à réaliser tous les jours, comme l’envoi par sms du nombre de vues sur mon blog, ou bien même le traitement de ma timeline Facebook qui est en partie automatisée. J’ai donc dû créer un scheduler pour chacun de ces cas, qui est d’ailleurs bien souvent le même. Actuellement en travaillant au contact des startups, j’ai vu que beaucoup de personnes ont la même problématique. J’ai donc décidé de packager le mien afin qu’il soit utile pour tous !

Les briques de Windows Azure que j’utilise

Pour mon scheduler, il suffit d’une simple Windows Azure Queue actuellement et bien entendu d’un système qui lit celle-ci. Pour ma part j’utilise des Worker Roles puisque j’en ai le plus souvent dans mes projets.

Plus que des mots, du code !

Alors tout commence par des “actions” à exécuter de façon régulière. Pour cela j’ai mis en place une classe qui s’appelle SchedulingAction dont il faut hériter pour déclarer son action comme ci-dessous.

    public class Action1 : SchedulingAction
    {
    public override void DoWork()
    {
    TableStorageLog.WriteLog(Name);
    }
    }
    

Cette classe SchedulingAction est abstraite et ne contient que très peu de propriétés comme on peut le voir :

    public abstract class SchedulingAction
    {
    /// <summary>
    /// Name of this action
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Delay to the next execution
    /// </summary>
    public TimeSpan? Delay { get; set; }

    /// <summary>
    /// Application Name (can be null, but i advise if you use the same table storage between multiple applications)
    /// </summary>
    public string ApplicationName { get; set; }

    /// <summary>
    /// Action to execute
    /// </summary>
    public abstract void DoWork();
    }
    

Le principe est donc simple, il suffit d’hériter de ma classe SchedulingAction, de définir le traitement à réaliser puis de les définir comme ci-dessous :

    scheduler.AddAction(new Action1() { Name = "Action 1", Delay = new TimeSpan(0, 0, 30) });
    scheduler.AddAction(new Action2() { Name = "Action 2", Delay = new TimeSpan(0, 2, 0) });
    scheduler.AddAction(new Action3() { Name = "Action 3", Delay = new TimeSpan(0, 5, 0) });
    scheduler.AddAction(new Action4() { Name = "Action 4" });
    

Le principe est de lire les actions, de les exécuter, de les supprimer et de les réempiler si nécessaire. Il y a donc deux méthodes que j’ai mises en place :

  • GetAction : qui permet de récupérer une action et supprime celle-ci des actions à exécuter.
  • ExecuteAction : qui permet de récupérer une action, l’exécuter, puis la reémpiler correctement si besoin.

Typiquement j’utilise la première méthode lorsque le calcul du délai d’exécution entre deux tâches peut-être variable. Et la deuxième lorsque c’est une tâche récurrente qui se déroule à intervalle régulier.

Où trouver ce scheduler

Vous pouvez retrouver les sources sur GitHub : le code source du scheduler ainsi qu’un Worker Role de démonstration. Et bien entendu, vous pouvez retrouver cela sur Nuget.

En conclusion

Bien qu’il ne comporte pas toutes les features du scheduler officiel de Windows Azure, celui-ci est très simple à mettre en place. Je pense que je réaliserai une update de ma librairie, si celle-ci est utilisée, afin qu’elle utilise le scheduler officiel.

Nombre de vue : 53

COMMENTAIRES 1 commentaire

  1. Bonjour Wilfried,

    Dans mon article et ma solution, j’ai utiliser Quartz.NET sans base de données.

    Le tout est en mémoire avec une schedule double pour éviter les problèmes lier au taches de maintenance de Windows Azure.

AJOUTER UN COMMENTAIRE