Die einzigartige Aufgabenfunktion in Asynq stellt sicher, dass sich nur eine Aufgabe in der Redis-Warteschlange befindet.

Wenn Sie Aufgaben deduplizieren und doppelte Aufgaben vermeiden möchten, ist diese Funktion sehr nützlich.

Überblick

Es gibt zwei Methoden, um die Einzigartigkeit von Aufgaben in Asynq zu gewährleisten.

  1. Verwendung der TaskID-Option: Generieren Sie selbst eine eindeutige Aufgaben-ID.
  2. Verwendung der Unique-Option: Lassen Sie Asynq eine Eindeutigkeitssperre für die Aufgabe erstellen.

Verwendung der TaskID-Option

Wenn Sie die erste Methode wählen, können Sie sicherstellen, dass es zu einem bestimmten Zeitpunkt nur eine Aufgabe mit einer bestimmten Aufgaben-ID gibt. Wenn Sie versuchen, eine weitere Aufgabe mit derselben Aufgaben-ID in die Warteschlange einzufügen, wird ein ErrTaskIDConflict-Fehler zurückgegeben.

// Die erste Aufgabe sollte in Ordnung sein
_, err := client.Enqueue(task, asynq.TaskID("mytaskid"))

// Die zweite Aufgabe wird fehlschlagen, err wird ErrTaskIDConflict sein (vorausgesetzt, die erste Aufgabe wurde noch nicht verarbeitet)
_, err = client.Enqueue(task, asynq.TaskID("mytaskid"))

Verwendung der Unique-Option

Die zweite Methode basiert auf einer Eindeutigkeitssperre. Beim Einreihen einer Aufgabe unter Verwendung der Unique-Option überprüft der Client, ob er die Sperre für die angegebene Aufgabe erhalten kann. Die Aufgabe wird nur in die Warteschlange eingereiht, wenn die Sperre erhalten werden kann. Wenn eine andere Aufgabe bereits die Sperre hält, gibt der Client einen Fehler zurück (siehe den untenstehenden Beispielcode, wie Fehler überprüft werden).

Die Eindeutigkeitssperre ist mit einer TTL (Time to Live) verbunden, um das Halten der Sperre dauerhaft zu vermeiden. Die Sperre wird nach der TTL oder nachdem die Aufgabe erfolgreich vor Ablauf der TTL verarbeitet wurde, freigegeben.

Eine wichtige Sache ist zu beachten, dass die einzigartige Aufgabenfunktion in Asynq eine Best-Effort-Eindeutigkeit ist. Mit anderen Worten, wenn die Sperre abgelaufen ist, bevor die Aufgabe verarbeitet wurde, kann eine doppelte Aufgabe in die Warteschlange eingereiht werden.

Die Einzigartigkeit der Aufgabe basiert auf den folgenden Attributen:

  • Typ
  • Nutzdaten
  • Warteschlange

Daher werden, wenn Aufgaben mit demselben Typ und Nutzdaten in dieselbe Warteschlange eingereiht werden, solange die Sperre nicht freigegeben ist, keine weiteren Aufgaben mit denselben Attributen in die Warteschlange eingereiht.

c := asynq.NewClient(redis)

t1 := asynq.NewTask("example", []byte("hallo"))

// t1 wird die Eindeutigkeitssperre für die nächste Stunde halten.
err := c.Enqueue(t1, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
    // Mit doppelter Aufgabe umgehen
case err != nil:
    // Andere Fehler behandeln
}

t2 := asynq.NewTask("example", []byte("hallo"))

// t2 kann nicht eingereiht werden, da es eine Kopie von t1 ist.
err = c.Enqueue(t2, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
    // Mit doppelter Aufgabe umgehen
case err != nil:
    // Andere Fehler behandeln
}

In obigem Beispiel wird t2 nicht eingereiht, da es eine Kopie von t1 ist. Sie können errors.Is verwenden, um den zurückgegebenen error-Wert zu überprüfen und festzustellen, ob er den asynq.ErrDuplicateTask-Fehler umschließt.