12 votes

Conditions d'erreur et tentatives dans gearman ?

Quelqu'un peut-il me guider sur la façon dont Gearman effectue des tentatives lorsque des exceptions se produisent ? exceptions ou lorsque des erreurs se produisent ?

J'utilise le client python gearman dans une application Django et mes travailleurs sont sont lancés comme une commande Django. J'ai lu ceci article de blog qui réessaie en cas d'erreur ne sont pas directes et qu'elles nécessitent l'intervention de sys.exit du côté du travailleur.

Est-ce que cela a été corrigé pour réessayer peut-être avec sendFail ou sendException ? De plus, Gearman supporte-t-il les tentatives avec l'algorithme des exponentielles - par exemple si Si un échec SMTP se produit, il réessaie après 2, 4, 8, 16 secondes, etc.

24voto

Aurimas Points 1653

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X