Fitur Tugas Unik di Asynq memastikan bahwa hanya ada satu tugas dalam antrean Redis.

Ketika Anda ingin menghapus tugas duplikat dan menghindari tugas ganda, fitur ini sangat berguna.

Gambaran

Ada dua metode untuk memastikan keunikan tugas di Asynq.

  1. Menggunakan opsi TaskID: Hasilkan ID tugas unik sendiri.
  2. Menggunakan opsi Unique: Biarkan Asynq membuat kunci keunikan untuk tugas tersebut.

Menggunakan Opsi TaskID

Jika Anda memilih metode pertama, Anda dapat memastikan bahwa hanya ada satu tugas dengan ID tugas tertentu pada waktu tertentu. Jika Anda mencoba untuk mengantre tugas lain dengan ID tugas yang sama, itu akan mengembalikan kesalahan ErrTaskIDConflict.

// Tugas pertama seharusnya baik-baik saja
_, err := client.Enqueue(task, asynq.TaskID("mytaskid"))

// Tugas kedua akan gagal, err akan menjadi ErrTaskIDConflict (asumsikan tugas pertama belum diproses)
_, err = client.Enqueue(task, asynq.TaskID("mytaskid"))

Menggunakan Opsi Unique

Metode kedua ini didasarkan pada kunci keunikan. Saat mengantre tugas menggunakan opsi Unique, Client akan memeriksa apakah bisa memperoleh kunci untuk tugas yang diberikan. Tugas hanya akan diantre jika kunci dapat diperoleh. Jika tugas lain sudah memegang kunci, Client akan mengembalikan kesalahan (lihat contoh kode di bawah ini tentang cara memeriksa kesalahan).

Kunci keunikan terkait dengan TTL (time to live) untuk menghindari memegang kunci secara permanen. Kunci akan dilepaskan setelah TTL atau setelah tugas berhasil diproses sebelum TTL.

Hal penting yang perlu dicatat adalah bahwa fitur tugas unik di Asynq adalah pengecualian keunikan terbaik. Dengan kata lain, jika kunci telah kedaluwarsa sebelum tugas diproses, tugas duplikat dapat diantre.

Keunikan tugas didasarkan pada atribut-atribut berikut:

  • Tipe
  • Muatan
  • Antrean

Oleh karena itu, jika terdapat tugas dengan jenis dan muatan yang sama yang diantre ke antrean yang sama, tugas lain dengan atribut yang sama tidak akan diantre sampai kunci dilepaskan.

c := asynq.NewClient(redis)

t1 := asynq.NewTask("contoh", []byte("halo"))

// t1 akan memegang kunci keunikan untuk satu jam ke depan.
err := c.Enqueue(t1, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
    // Tangani tugas duplikat
case err != nil:
    // Tangani kesalahan lain
}

t2 := asynq.NewTask("contoh", []byte("halo"))

// t2 tidak dapat diantre karena itu merupakan duplikat dari t1.
err = c.Enqueue(t2, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
    // Tangani tugas duplikat
case err != nil:
    // Tangani kesalahan lain
}

Pada contoh di atas, t2 tidak akan diantre karena itu merupakan duplikat dari t1. Anda dapat menggunakan errors.Is untuk memeriksa nilai error yang dikembalikan untuk menentukan apakah itu melingkupi kesalahan asynq.ErrDuplicateTask.