Mise en place Hangfire

Hangfire

Hangfire permet d’externaliser la gestion des tâches au sein d’une application. Owin assure la portabilité dans tous les environnements et pas seulement ASP.NET (ASP.NET web applications, non-ASP.NET web applications, console applications ou Windows services).

Prérequis :

  • .NET Framework 4.5
  • Persistent storage
  • Json library ≥ 5.0.1
  • SQL serveur 2012 (Utilisation de la dll spécifique Hangfire.sqlserver | possibilité d'utiliser d'autres SGBD)
  • Références supplémentaires : Microsoft.Owin v3.0.0.0 + Owin V1.0.0.0

Il existe 3 types de jobs qui peuvent tourner en tâches de fonds, fire-and-forget (Lance une fois le job puis “l’oubli”), delayed (Active un job planifié) et recurring (Active un job de façon récurrente).

Hangfire garde en mémoire les informations des jobs en arrière-plan ainsi que leur paramétrage en base. Cela permet à Hangfire de reprendre son travail là où il s’était arrêté en cas de redémarrage de l’application ou du serveur. C’est la principale différence avec les gestionnaires de tâches tels que CLR’s Thread Pool.

Different storage backends are supported:

  • SQL Azure, SQL Server 2008 R2 (and later of any edition, including Express)
  • Redis

SQL Server storage can be empowered with MSMQ or RabbitMQ to lower the processing latency.

GlobalConfiguration.Configuration.UseSqlServerStorage("db_connection");

Quick Start

Plusieurs packages sont disponibles sous NuGet

PM> Install-Package Hangfire

Après installation du package, mettre en place la class OWIN Startup comme suit:

using Hangfire; 

public void Configuration(IAppBuilder app)

{

    GlobalConfiguration.Configuration.UseSqlServerStorage("<connection string or its name>");

    app.UseHangfireDashboard();

    app.UseHangfireServer();

}

Par défaut seul les accès locaux au gestionnaire des tâches sont autorisés. Dashboard authorization doit être paramétré pour y avoir accès à distance.

#Obvious : Une base de données doit être créée au préalable.

 

Mise en place des jobs.... & relax !

a. Fire and Forget

Principal type de job, une fois le job créé, il vient se stocker automatiquement dans la file d’attente par défaut. Bien sûr, plusieurs files d’attente peuvent être gérées par une même instance Hangfire.

BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));

b. Delayed

Pour un job nécessitant un certain délai avant activation, utilisez la méthode suivante :

BackgroundJob.Schedule(() => Console.WriteLine("Delayed"), TimeSpan.FromDays(1));

Une fois le délai expiré, le job s’exécutera dans la file d’attente par défaut (ou celle paramétrée au préalable) tel un job “Fire and Forget”.

c. Recurring

Pour appeler un job de façon récurrente, utilisez la class RecurringJob. Vous pouvez personnaliser la récurrence d’appel du job via une expression Cron, pour des configurations plus complexes.

RecurringJob.AddOrUpdate(() => Console.WriteLine("Daily Job"), Cron.Daily);

IMPRESSION_Capture_cron

d. "Continuations"

Cette option permet de définir des enchaînements complexes de job, en créant une chaîne de jobs (un cycle de vie des jobs en quelque sorte)

var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));
BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));

e. ... & relax !

Le relax => Lors du 1er lancement de la solution, Hangfire va initialiser la base de données dans son propre schéma !

Hangfire sauvegarde pour vous l’état des jobs en base, et les exécute en arrière-plan. Cela implique que vous pouvez stopper les threads de travail d’Hangfire, supprimer l’application du domaine ou même terminer un job en cours d’exécution, vous serez toujours à même de retrouver l’état de vos jobs via la console d’administration web.

Hangfire a la possibilité de flagger un job comme « terminé » seulement si la méthode s’exécute jusqu’à la dernière ligne, il saura donc si le job est tombé en erreur s’il n’atteint pas cette ligne. Hangfire possède des outils de relances automatiques qui peuvent gérer les erreurs de stockage ou d’exécution de code.

f. Exemple de ma solution

Startup.cs

using Hangfire;
using Microsoft.Owin;
using Owin;
using HangfireGidec.Impression;
 
[assembly: OwinStartup(typeof(HangfireGidec.Startup))]
namespace HangfireGidec
{
    public class Startup
    {
        private ImpressionMasse im = new ImpressionMasse();
        private CleanRepImp cri = new CleanRepImp();
 
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configuration.UseSqlServerStorage(System.Configuration.ConfigurationManager.ConnectionStrings["GidecBd"].ToString());
 
            // Ajout du job d'impression en masse (toutes les heures)
            RecurringJob.AddOrUpdate(() => im.ImprimerEnMasse(), "0/15 * * * *", null, "default");
 
            // Ajout du job de nettoyage du répertoire contenant les questionnaires à imprimer
            RecurringJob.AddOrUpdate(() => cri.Clean(), "0 15 19 * *", null, "default");
 
            app.UseHangfireDashboard();
            app.UseHangfireServer();
        }
    }
}

Exemple avec l'impression en masse :

private ImpressionMasse im = new ImpressionMasse();

ImpressionMasse.cs

public partial class ImpressionMasse
 {
     public ICollection<WKF_SERVICE_TASKS> ListTaks { get; set; } // = new ObservableCollection<WKF_SERVICE_TASKS>();
     public List<int> ListIdQuest { get; set; }
     public string TypeQuest { get; set; }
     public string DefaultPrinter { get; set; }

     public void ImprimerEnMasse()
     {
         try
         {
             InitServiceTasks();
             PrintJob();
             CleanServiceTasks();
         }
         catch (Exception e)
         {
             Console.WriteLine("## erreur PRINTJOB - IMPRIMER EN MASSE : e => " + e.InnerException);
         }
     }
 }

 

Gestion de l'interface

Lancer / Annuler / liste des files d’attentes / liste des serveurs / gestion des logs de traitement des job / etc…

L’interface est on ne peut plus claire et précise.

Quelques exemples d’utilisation :

Page d’accueil

IMPRESSION_interface_01

 

Job en cours

IMPRESSION_interface_02

 

Lancement d’un job programmé

Sélectionnez un job, et cliquez sur "trigger now"

IMPRESSION_interface_03

Cliquez sur « Trigger now » pour lancer le job sélectionné

 

Résultat d’un job qui s’est déroulé correctement

IMPRESSION_interface_04

 

Log du job

IMPRESSION_interface_05

 

Les liens utiles

Un comparatif des différents gestionnaires de tâches

Hangfire

Expression CRON

A venir...

Un second blog sur le debug des tâches programmées au sein d'Hangfire sera disponible sous peu.

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.