Asynq의 고유 작업 기능은 Redis 대기열에 하나의 작업만 있는지를 보장합니다.
작업을 중복 처리하지 않고 중복 작업을 피하려는 경우 이 기능이 매우 유용합니다.
개요
Asynq에서 작업의 고유성을 보장하는 두 가지 방법이 있습니다.
-
TaskID
옵션 사용: 직접 고유한 작업 ID를 생성합니다. -
Unique
옵션 사용: Asynq가 작업에 대해 고유성 잠금을 생성하도록 합니다.
TaskID
옵션 사용
첫 번째 방법을 선택하면 특정 작업 ID를 가진 작업이 언제나 하나만 있는지를 보장할 수 있습니다. 동일한 작업 ID로 다른 작업을 enque하려고 하면 ErrTaskIDConflict
오류가 반환됩니다.
// 첫 번째 작업은 정상적으로 처리됩니다
_, err := client.Enqueue(task, asynq.TaskID("mytaskid"))
// 두 번째 작업은 실패합니다. err은 ErrTaskIDConflict일 것입니다 (첫 번째 작업이 아직 처리되지 않았다고 가정)
_, err = client.Enqueue(task, asynq.TaskID("mytaskid"))
Unique
옵션 사용
두 번째 방법은 고유성 잠금을 기반으로 합니다. Unique
옵션을 사용하여 작업을 enque할 때, Client
는 주어진 작업에 대한 잠금을 획들할 수 있는지 확인합니다. 잠금을 획들할 수 있는 경우에만 작업이 enqueued됩니다. 다른 작업이 이미 잠금을 보유하고 있는 경우, Client
는 오류를 반환합니다 (오류를 확인하는 예제 코드는 아래에 있습니다).
고유성 잠금은 영구적으로 잠금을 보유하지 않도록 TTL (Time to Live)과 연관되어 있습니다. TTL 이후에 또는 작업이 TTL 이전에 성공적으로 처리된 경우에 잠금은 해제됩니다.
Asynq의 고유 작업 기능은 최선의 노력으로 고유성을 보장합니다. 다시 말해, 작업이 처리되기 전에 잠금이 만료된 경우 중복 작업이 enqueued될 수 있습니다.
작업의 고유성은 다음 속성을 기반으로 합니다:
- 유형 (Type)
- 페이로드 (Payload)
- 대기열 (Queue)
따라서 동일한 유형 및 페이로드를 가진 작업이 같은 대기열에 enqueued된 경우, 잠금이 해제될 때까지 동일한 속성을 가진 다른 작업이 enqueued되지 않습니다.
c := asynq.NewClient(redis)
t1 := asynq.NewTask("example", []byte("hello"))
// t1은 다음 시간 동안 고유성 잠금을 유지할 것입니다.
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의 중복이므로 enqueued될 수 없습니다.
err = c.Enqueue(t2, asynq.Unique(time.Hour))
switch {
case errors.Is(err, asynq.ErrDuplicateTask):
// 중복 작업 처리
case err != nil:
// 다른 오류 처리
}
위의 예제에서 t2
는 t1
의 중복이므로 enqueued될 수 없습니다. 반환된 error
값이 asynq.ErrDuplicateTask
오류를 감싸는지 확인하기 위해 errors.Is
를 사용할 수 있습니다.