Celery is een krachtig framework dat asynchrone taakverwerking ondersteunt. De @shared_task decorator wordt gebruikt om een taak (Task) te definiëren en met name de opties bind, autoretry_for, retry_backoff, max_retries kunnen de betrouwbaarheid en geautomatiseerde foutafhandeling van taken aanzienlijk verbeteren.

In dit artikel bekijken we de werking van elke optie en hoe je deze kunt gebruiken, evenals de veelvoorkomende verwarring en de beste oplossingen hiervoor.


1. bind=True

Definitie

bind=True zorgt ervoor dat de huidige taak (Task) als eerste parameter wordt doorgegeven, zodat self binnen de taak kan worden gebruikt. Hierdoor kun je toegang krijgen tot de status, methoden en eigenschappen van de taak.

Belangrijkste functionaliteit

  • Toegang tot taakstatus: Je kunt toegang krijgen tot taak-ID, verzoekinformatie, enzovoort, om de status te controleren of loggen.
  • Expliciete retry-logica: Je kunt de retry-logica handmatig implementeren via de self.retry() methode.

Voorbeeld

@shared_task(bind=True)
def my_task(self, some_arg):
    print(f"Task ID: {self.request.id}")  # Taak-ID weergeven
    self.retry()  # Taak opnieuw proberen

2. autoretry_for=(ExceptionType, ...)

Definitie

Stel in dat Celery de taak automatisch moet herstarten wanneer de opgegeven uitzonderingstype optreedt. Dit automatiseert de uitzonderingafhandeling en herstart zonder dat de ontwikkelaar self.retry() expliciet hoeft aan te roepen.

Let op

  • Als je autoretry_for gebruikt: Omdat herstarten automatisch gebeurt, moet je ervoor zorgen dat het niet duplicaat is met self.retry().
  • Problemen bij menggebruik: Als je autoretry_for en self.retry() gelijktijdig gebruikt, kan dit leiden tot dubbele herstarts voor dezelfde uitzondering.

Voorbeeld

Aangeraden manier: alleen gebruik van 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()  # Werpt een uitzondering als de statuscode geen 200 is
Wanneer je alleen onder specifieke voorwaarden expliciet opnieuw probeert (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"Proberen opnieuw vanwege fout: {e}")
        self.retry(exc=e)  # Expliciete herstart

3. retry_backoff=True

Definitie

Activeert een exponentieel backoff waarbij de herstartintervallen geleidelijk toenemen. De eerste herstart is onmiddellijk, daarna stijgen de intervallen naar 1 seconde, 2 seconden, 4 seconden, ...

Belangrijkste functionaliteit

  • Vermindert serverbelastingen en verwerkt netwerkstoringen efficiënt.
  • Backoff-tijd kan worden aangepast via de standaardinstellingen van Celery.

Voorbeeld

@shared_task(bind=True, autoretry_for=(requests.RequestException,), retry_backoff=True)
def my_task(self):
    # De eerste herstart na 1 seconde, de tweede herstart na 2 seconden...
    raise requests.RequestException("Gesimuleerde fout")

4. max_retries

Definitie

Stelt het maximum aantal herstarts van een taak in. Als de taak niet succesvol is na het opgegeven aantal herstarts, wordt deze als mislukt geregistreerd.

Belangrijkste functionaliteit

  • Voorkomt oneindige herstarts en beperkt het gebruik van serverbronnen.
  • Afhankelijk van de voorwaarden kan de taak worden geregistreerd of andere logica worden uitgevoerd.

Voorbeeld

@shared_task(bind=True, autoretry_for=(requests.RequestException,), retry_backoff=True, max_retries=5)
def my_task(self):
    raise requests.RequestException("Gesimuleerde fout")

5. Let op bij gebruik: autoretry_for vs self.retry()

Juiste gebruiksgids

  1. Bij gebruik van autoretry_for: Aangezien de automatische herstart is ingesteld, hoef je self.retry() niet expliciet aan te roepen. Dit kan helpen bij het schrijven van eenvoudiger code voor herstarten bij specifieke uitzonderingen.
  2. Bij gebruik van self.retry(): Gebruik dit wanneer je extra acties (bijvoorbeeld loggen, specifieke voorwaarden controleren) nodig hebt voor de herstart. Wees voorzichtig om te voorkomen dat je dubbel gebruik van autoretry_for.

6. Opties samenvatting

Optie Beschrijving
bind=True Toegang tot de status en methodes van de taak via self.
autoretry_for Automatisch opnieuw proberen van de taak wanneer specifieke uitzonderingen optreden.
retry_backoff Activeert exponentieel backoff voor het geleidelijk verhogen van de herstartintervallen.
max_retries Beperkt het maximum aantal herstarts om mislukte taakvoorwaarden te definiëren.
Begrijpen van Celery @shared_task opties

7. Conclusie

De @shared_task opties van Celery zijn nuttig voor het effectief afhandelen van taakfouten en het verhogen van de betrouwbaarheid.

  • Als je autoretry_for gebruikt: Let op dat de retry-logica geautomatiseerd is, en zorg ervoor dat het niet dubbel is met self.retry().
  • Als er conditionele logica of extra acties nodig zijn, kun je gebruik maken van self.retry().

Om taken met Celery betrouwbaar uit te voeren, probeer deze opties te combineren en schrijf de meest geoptimaliseerde code voor jouw situatie! 😊