คุณลักษณะงานที่ไม่ซ้ำกันใน Asynq ทำให้มั่นใจได้ว่ามีเพียงงานเดียวในคิว Redis เท่านั้น
เมื่อคุณต้องการลบงานที่ซ้ำกันและป้องกันไม่ให้มีงานที่ซ้ำกัน คุณลักษณะนี้เป็นประโยชน์อย่างมาก
ภาพรวม
มีวิธีการสองประการในการให้คุณลักษณะงานที่ไม่ซ้ำกันใน Asynq
- การใช้ตัวเลือก
TaskID
: สร้างรหัสงานที่ไม่ซ้ำกันเอง - การใช้ตัวเลือก
Unique
: ให้ Asynq สร้างการล็อกที่ไม่ซ้ำกันสำหรับงาน
การใช้ TaskID
Option
หากคุณเลือกวิธีการแรก คุณสามารถมั่นใจได้ว่ามีเพียงงานเดียวที่มีรหัสงานที่กำหนดไว้ในทุกเวลาที่กำหนด หากคุณพยายามใส่งานอีกครั้งที่มีรหัสงานเดียวกัน มันจะส่งคืนข้อผิดพลาด ErrTaskIDConflict
// งานแรกควรทำได้
_, err := client.Enqueue(task, asynq.TaskID("mytaskid"))
// งานที่สองจะทำล้มเหลว err จะเป็น ErrTaskIDConflict (โดยสมมติว่างานแรกยังไม่ได้รับการประมวลผล)
_, err = client.Enqueue(task, asynq.TaskID("mytaskid"))
การใช้ Unique
Option
วิธีการที่สองเป็นการล็อกที่ไม่ซ้ำกัน เมื่อนำงานเข้าคิวโดยใช้ตัวเลือก Unique
ตัว Client
จะตรวจสอบว่าสามารถได้รับล็อกสำหรับงานที่กำหนดหรือไม่ งานจะถูกนำเข้าคิวเฉพาะเมื่อสามารถได้รับล็อก หากมีงานอื่นถือครองล็อกอยู่แล้ว, ตัว Client
จะส่งคืนข้อผิดพลาด (ดูตัวอย่างโค้ดด้านล่างเพื่อทบทวนว่าวิธีการแก้ปัญหาข้อผิดพลาด)
ล็อกที่ไม่ซ้ำกันเชื่อมโยงกับ TTL (time to live) เพื่อหลีกเลี่ยงการถือล็อกอยู่ตลอดไป ล็อกจะถูกปล่อยหลังจาก TTL หรือหลังจากงานได้รับการประมวลผลเรียบร้อยก่อน TTL
สิ่งที่สำคัญที่จะทำความเข้าใจคือ คุณลักษณะงานที่ไม่ซ้ำกันใน Asynq เน้นการล็อกที่ไม่ซ้ำกันด้วยความพยายาม ที่ดีที่สุด กล่าวคือ หากล็อกได้หมดอายุก่อนที่งานได้รับการประมวลผล งานที่ซ้ำกันอาจนำเข้าคิวได้
คุณลักษณะงานที่ไม่ซ้ำกันขึ้นอยู่กับลักษณะต่อไปนี้:
- ประเภท
- ดาวน์โหลด
- คิว
ดังนั้น, หากมีงานที่มีประเภทและดาวน์โหลดเหมือนกันถูกนำเข้าคิวไปยังคิวเดียวกัน, งานอื่นที่มีลักษณะเหล่านี้เหมือนกันจะไม่ถูกนำเข้าคิวไปยังคิวเดียวกันจนกว่าล็อกจะถูกปล่อย
c := asynq.NewClient(redis)
t1 := asynq.NewTask("example", []byte("hello"))
// t1 จะถือล็อกที่ไม่ซ้ำกันไว้ถึง 1 ชั่วโมงถัดไป
err := c.Enqueue(t1, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
// จัดการกับงานที่ซ้ำกัน
case err != nil:
// จัดการกับข้อผิดพลาดอื่น ๆ
}
t2 := asynq.NewTask("example", []byte("hello"))
// t2 ไม่สามารถนำเข้าคิวได้เนื่องจากเป็นงานที่ซ้ำกับ t1
err = c.Enqueue(t2, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
// จัดการกับงานที่ซ้ำกัน
case err != nil:
// จัดการกับข้อผิดพลาดอื่น ๆ
}
ในตัวอย่างข้างต้น, t2
จะไม่ถูกนำเข้าคิวเนื่องจากเป็นงานที่ซ้ำกันกับ t1
คุณสามารถใช้ errors.Is
ในการตรวจสอบค่า error
ที่ส่งคืนเพื่อรายงานว่ามันห่อหุ้มข้อผิดพลาด asynq.ErrDuplicateTask
หรือไม่