D'après ce que j'ai compris, Gearman utilise une approche très "ce n'est pas mon affaire" - par exemple, il n'intervient pas dans les tâches effectuées, à moins que les travailleurs ne se plantent. Les messages de réussite ou d'échec sont censés être gérés par le client, et non par le serveur Gearman lui-même.
Dans les emplois d'avant-plan, cela implique que tous les sendFail()
/ sendException()
et autres send*()
sont dirigés vers le client et c'est à ce dernier de décider s'il faut réessayer le travail ou non. C'est logique, car il n'est parfois pas nécessaire d'effectuer une nouvelle tentative.
Dans les tâches d'arrière-plan, tous les send*()
perdent leur sens, car aucun client n'écoute les rappels. Par conséquent, les messages envoyés seront simplement ignorés par Gearman. La seule condition pour que le travail soit réessayé est que le travailleur se plante (ce qui peut être émulé avec une fonction exit(XX)
où la commande XX
est une valeur non nulle). Bien sûr, ce n'est pas quelque chose que vous voulez faire, car les travailleurs sont généralement censés être des processus de longue durée, et non pas ceux qui doivent être redémarrés après chaque travail infructueux.
Personnellement, j'ai résolu ce problème en étendant la classe GearmanJob par défaut, où j'intercepte les appels à send*()
et de mettre en œuvre moi-même le mécanisme de réessai. Pour l'essentiel, je transmets toutes les données relatives aux tentatives (nombre maximal de tentatives, nombre de tentatives déjà effectuées) avec une charge de travail et je m'occupe de tout moi-même. C'est un peu lourd, mais je comprends pourquoi Gearman fonctionne de cette manière - il vous permet simplement de gérer toute la logique de l'application.
Enfin, en ce qui concerne la possibilité de relancer des tâches avec un délai exponentiel (ou tout autre délai d'ailleurs). Gearman dispose d'une fonctionnalité permettant d'ajouter des tâches retardées (recherchez SUBMIT_JOB_EPOCH
dans le documentation du protocole ), mais je ne suis pas sûr de son statut - l'extension PHP et, je pense, le module Python ne le supportent pas et la documentation indique qu'il peut être supprimé à l'avenir. Mais j'ai cru comprendre que cela fonctionnait pour l'instant - il suffit de soumettre des requêtes de socket brut à Gearman pour que cela se produise (et la partie exponentielle devrait être implémentée de votre côté, aussi).
Cependant, cet article de blog affirme que la mise en œuvre de SUBMIT_JOB_EPOCH n'est pas bien adaptée. Il utilise node.js et setTimeout()
pour le faire fonctionner, j'ai vu d'autres personnes utiliser l'utilitaire unix at
de faire de même. En tout état de cause, Gearman ne le fera pas à votre place. Il se concentrera sur la fiabilité, mais vous laissera vous concentrer sur toute la logique.