2
0
mirror of https://github.com/hibiken/asynq.git synced 2024-11-15 20:08:46 +08:00

Update RDB.Retry to remove message from deadlines set

This commit is contained in:
Ken Hibino 2020-06-18 10:25:01 -07:00
parent bee784c052
commit 02b653df72
2 changed files with 51 additions and 15 deletions

View File

@ -315,9 +315,10 @@ func (r *RDB) ScheduleUnique(msg *base.TaskMessage, processAt time.Time, ttl tim
} }
// KEYS[1] -> asynq:in_progress // KEYS[1] -> asynq:in_progress
// KEYS[2] -> asynq:retry // KEYS[2] -> asynq:deadlines
// KEYS[3] -> asynq:processed:<yyyy-mm-dd> // KEYS[3] -> asynq:retry
// KEYS[4] -> asynq:failure:<yyyy-mm-dd> // KEYS[4] -> asynq:processed:<yyyy-mm-dd>
// KEYS[5] -> asynq:failure:<yyyy-mm-dd>
// ARGV[1] -> base.TaskMessage value to remove from base.InProgressQueue queue // ARGV[1] -> base.TaskMessage value to remove from base.InProgressQueue queue
// ARGV[2] -> base.TaskMessage value to add to Retry queue // ARGV[2] -> base.TaskMessage value to add to Retry queue
// ARGV[3] -> retry_at UNIX timestamp // ARGV[3] -> retry_at UNIX timestamp
@ -327,15 +328,19 @@ local x = redis.call("LREM", KEYS[1], 0, ARGV[1])
if x == 0 then if x == 0 then
return redis.error_reply("NOT FOUND") return redis.error_reply("NOT FOUND")
end end
redis.call("ZADD", KEYS[2], ARGV[3], ARGV[2]) x = redis.call("ZREM", KEYS[2], ARGV[1])
local n = redis.call("INCR", KEYS[3]) if x == 0 then
if tonumber(n) == 1 then return redis.error_reply("NOT FOUND")
redis.call("EXPIREAT", KEYS[3], ARGV[4])
end end
local m = redis.call("INCR", KEYS[4]) redis.call("ZADD", KEYS[3], ARGV[3], ARGV[2])
if tonumber(m) == 1 then local n = redis.call("INCR", KEYS[4])
if tonumber(n) == 1 then
redis.call("EXPIREAT", KEYS[4], ARGV[4]) redis.call("EXPIREAT", KEYS[4], ARGV[4])
end end
local m = redis.call("INCR", KEYS[5])
if tonumber(m) == 1 then
redis.call("EXPIREAT", KEYS[5], ARGV[4])
end
return redis.status_reply("OK")`) return redis.status_reply("OK")`)
// Retry moves the task from in-progress to retry queue, incrementing retry count // Retry moves the task from in-progress to retry queue, incrementing retry count
@ -357,7 +362,7 @@ func (r *RDB) Retry(msg *base.TaskMessage, processAt time.Time, errMsg string) e
failureKey := base.FailureKey(now) failureKey := base.FailureKey(now)
expireAt := now.Add(statsTTL) expireAt := now.Add(statsTTL)
return retryCmd.Run(r.client, return retryCmd.Run(r.client,
[]string{base.InProgressQueue, base.RetryQueue, processedKey, failureKey}, []string{base.InProgressQueue, base.KeyDeadlines, base.RetryQueue, processedKey, failureKey},
msgToRemove, msgToAdd, processAt.Unix(), expireAt.Unix()).Err() msgToRemove, msgToAdd, processAt.Unix(), expireAt.Unix()).Err()
} }

View File

@ -694,9 +694,27 @@ func TestScheduleUnique(t *testing.T) {
func TestRetry(t *testing.T) { func TestRetry(t *testing.T) {
r := setup(t) r := setup(t)
t1 := h.NewTaskMessage("send_email", map[string]interface{}{"subject": "Hola!"}) now := time.Now()
t2 := h.NewTaskMessage("gen_thumbnail", map[string]interface{}{"path": "some/path/to/image.jpg"}) t1 := &base.TaskMessage{
t3 := h.NewTaskMessage("reindex", nil) ID: xid.New(),
Type: "send_email",
Payload: map[string]interface{}{"subject": "Hola!"},
Timeout: 1800,
}
t1Deadline := int(now.Unix()) + t1.Timeout
t2 := &base.TaskMessage{
ID: xid.New(),
Type: "gen_thumbnail",
Payload: map[string]interface{}{"path": "some/path/to/image.jpg"},
Timeout: 3000,
}
t2Deadline := int(now.Unix()) + t2.Timeout
t3 := &base.TaskMessage{
ID: xid.New(),
Type: "reindex",
Payload: nil,
Timeout: 60,
}
t1.Retried = 10 t1.Retried = 10
errMsg := "SMTP server is not responding" errMsg := "SMTP server is not responding"
t1AfterRetry := &base.TaskMessage{ t1AfterRetry := &base.TaskMessage{
@ -706,21 +724,27 @@ func TestRetry(t *testing.T) {
Queue: t1.Queue, Queue: t1.Queue,
Retry: t1.Retry, Retry: t1.Retry,
Retried: t1.Retried + 1, Retried: t1.Retried + 1,
Timeout: t1.Timeout,
ErrorMsg: errMsg, ErrorMsg: errMsg,
} }
now := time.Now()
tests := []struct { tests := []struct {
inProgress []*base.TaskMessage inProgress []*base.TaskMessage
deadlines []h.ZSetEntry
retry []h.ZSetEntry retry []h.ZSetEntry
msg *base.TaskMessage msg *base.TaskMessage
processAt time.Time processAt time.Time
errMsg string errMsg string
wantInProgress []*base.TaskMessage wantInProgress []*base.TaskMessage
wantDeadlines []h.ZSetEntry
wantRetry []h.ZSetEntry wantRetry []h.ZSetEntry
}{ }{
{ {
inProgress: []*base.TaskMessage{t1, t2}, inProgress: []*base.TaskMessage{t1, t2},
deadlines: []h.ZSetEntry{
{Msg: t1, Score: float64(t1Deadline)},
{Msg: t2, Score: float64(t2Deadline)},
},
retry: []h.ZSetEntry{ retry: []h.ZSetEntry{
{ {
Msg: t3, Msg: t3,
@ -731,6 +755,9 @@ func TestRetry(t *testing.T) {
processAt: now.Add(5 * time.Minute), processAt: now.Add(5 * time.Minute),
errMsg: errMsg, errMsg: errMsg,
wantInProgress: []*base.TaskMessage{t2}, wantInProgress: []*base.TaskMessage{t2},
wantDeadlines: []h.ZSetEntry{
{Msg: t2, Score: float64(t2Deadline)},
},
wantRetry: []h.ZSetEntry{ wantRetry: []h.ZSetEntry{
{ {
Msg: t1AfterRetry, Msg: t1AfterRetry,
@ -747,6 +774,7 @@ func TestRetry(t *testing.T) {
for _, tc := range tests { for _, tc := range tests {
h.FlushDB(t, r.client) h.FlushDB(t, r.client)
h.SeedInProgressQueue(t, r.client, tc.inProgress) h.SeedInProgressQueue(t, r.client, tc.inProgress)
h.SeedDeadlines(t, r.client, tc.deadlines)
h.SeedRetryQueue(t, r.client, tc.retry) h.SeedRetryQueue(t, r.client, tc.retry)
err := r.Retry(tc.msg, tc.processAt, tc.errMsg) err := r.Retry(tc.msg, tc.processAt, tc.errMsg)
@ -759,7 +787,10 @@ func TestRetry(t *testing.T) {
if diff := cmp.Diff(tc.wantInProgress, gotInProgress, h.SortMsgOpt); diff != "" { if diff := cmp.Diff(tc.wantInProgress, gotInProgress, h.SortMsgOpt); diff != "" {
t.Errorf("mismatch found in %q; (-want, +got)\n%s", base.InProgressQueue, diff) t.Errorf("mismatch found in %q; (-want, +got)\n%s", base.InProgressQueue, diff)
} }
gotDeadlines := h.GetDeadlinesEntries(t, r.client)
if diff := cmp.Diff(tc.wantDeadlines, gotDeadlines, h.SortZSetEntryOpt); diff != "" {
t.Errorf("mismatch found in %q; (-want, +got)\n%s", base.KeyDeadlines, diff)
}
gotRetry := h.GetRetryEntries(t, r.client) gotRetry := h.GetRetryEntries(t, r.client)
if diff := cmp.Diff(tc.wantRetry, gotRetry, h.SortZSetEntryOpt); diff != "" { if diff := cmp.Diff(tc.wantRetry, gotRetry, h.SortZSetEntryOpt); diff != "" {
t.Errorf("mismatch found in %q; (-want, +got)\n%s", base.RetryQueue, diff) t.Errorf("mismatch found in %q; (-want, +got)\n%s", base.RetryQueue, diff)