Celery est un puissant framework qui prend en charge le traitement des tâches asynchrones. Le décorateur @shared_task est utilisé pour définir des tâches, et en particulier, en utilisant les options bind, autoretry_for, retry_backoff et max_retries, on peut considérablement améliorer la fiabilité des tâches et le traitement automatisé des erreurs.

Dans cet article, nous examinerons le fonctionnement et l'utilisation de chaque option, en abordant les confusions courantes ainsi que les meilleures solutions pour les résoudre.


1. bind=True

Définition

bind=True permet de passer la tâche actuelle en tant que premier paramètre, ce qui permet d'utiliser self à l'intérieur de la tâche. Cela permet d'accéder à l'état de la tâche, aux méthodes, aux attributs, etc.

Fonctionnalités principales

  • Accès à l'état de la tâche: On peut vérifier l'état ou enregistrer des informations en accédant à l'ID de la tâche, aux informations de la demande, etc.
  • Logique de réessai explicite: On peut implémenter manuellement la logique de réessai avec la méthode self.retry().

Exemple

@shared_task(bind=True)
def my_task(self, some_arg):
    print(f"ID de la tâche : {self.request.id}")  # Affichage de l'ID de la tâche
    self.retry()  # Réessayer la tâche

2. autoretry_for=(ExceptionType, ...)

Définition

Configure Celery pour que la tâche soit automatiquement réessayée lorsque le type d'exception spécifié se produit. Le développeur n'a pas besoin d'appeler explicitement self.retry() pour gérer les exceptions et automatiser les réessais.

Points d'attention

  • Lors de l'utilisation de autoretry_for: Étant donné que le réessai est effectué automatiquement, il faut faire attention à ne pas utiliser self.retry() en double.
  • Problèmes lors de l'utilisation combinée: Utiliser autoretry_for et self.retry() simultanément peut entraîner des réessais en double pour la même exception.

Exemple

Approche recommandée : utilisation uniquement de autoretry_for
import requests

@shared_task(bind=True, autoretry_for=(requests.RequestException,), retry_backoff=True)
def my_task(self, url):
    response = requests.get(url)
    response.raise_for_status()  # Lève une exception si le code d'état n'est pas 200
Utilisation explicite pour certaines conditions (self.retry())
import requests

@shared_task(bind=True, retry_backoff=True, max_retries=5)
def my_task(self, url):
    try:
        response = requests.get(url)
        response.raise_for_status()
    except requests.RequestException as e:
        print(f"Réessayer en raison de l'erreur : {e}")
        self.retry(exc=e)  # Réessayer explicitement

3. retry_backoff=True

Définition

Active l'augmentation exponentielle des délais de réessai. Le premier réessai se fait immédiatement, puis les réessais suivants sont espacés de 1 seconde, 2 secondes, 4 secondes... ainsi de suite.

Fonctionnalités principales

  • Réduit la charge sur le serveur et gère efficacement les pannes réseau.
  • Le temps de backoff peut être personnalisé via les paramètres par défaut de Celery.

Exemple

@shared_task(bind=True, autoretry_for=(requests.RequestException,), retry_backoff=True)
def my_task(self):
    # Le premier réessai est après 1 seconde, le deuxième réessai après 2 secondes...
    raise requests.RequestException("Échec simulé")

4. max_retries

Définition

Limite le nombre maximal de réessais pour la tâche. Si la tâche échoue après avoir été réessayée le nombre spécifié de fois, elle est enregistrée comme échouée.

Fonctionnalités principales

  • Évite les échecs de réessai infinis, limitant ainsi la consommation des ressources du serveur.
  • Permet d'enregistrer des informations sur les échecs ou d'exécuter d'autres logiques selon les conditions d'échec.

Exemple

@shared_task(bind=True, autoretry_for=(requests.RequestException,), retry_backoff=True, max_retries=5)
def my_task(self):
    raise requests.RequestException("Échec simulé")

5. Précautions lors de l'utilisation combinée : autoretry_for vs self.retry()

Guide d'utilisation correct

  1. Lors de l'utilisation de autoretry_for: Étant donné que le réessai est automatisé, il n'est pas nécessaire d'appeler explicitement self.retry(). On peut écrire un code succinct pour réessayer simplement en cas d'exception spécifique.
  2. Lors de l'utilisation de self.retry(): Cela est utilisé lorsque des travaux supplémentaires (comme l'écriture de journaux, la vérification de certaines conditions) sont nécessaires avant le réessai. Faites attention à ne pas ce chevaucher avec autoretry_for.

6. Résumé des options

Option Description
bind=True Accès à l'état et aux méthodes de la tâche via self.
autoretry_for Réessayer automatiquement la tâche lors de la survenue d'une exception spécifique.
retry_backoff Activer le backoff exponentiel pour augmenter progressivement l'intervalle de réessai.
max_retries Limite le nombre maximal de réessais pour définir les conditions d'échec de la tâche.
Comprendre les options @shared_task de Celery

7. Conclusion

Les options @shared_task de Celery sont utiles pour gérer efficacement les échecs de tâches et augmenter la fiabilité.

  • Si vous utilisez autoretry_for: Il est crucial de prêter attention à ce que cela n'entre pas en conflit avec self.retry().
  • Si une logique conditionnelle ou des travaux supplémentaires sont nécessaires, vous pouvez utiliser self.retry().

Pour mettre en œuvre solidement des tâches en utilisant Celery, essayez de combiner ces options et d'écrire un code optimisé en fonction de la situation ! 😊