2
0
mirror of https://github.com/hibiken/asynq.git synced 2025-10-26 11:16:12 +08:00

Add methods to rdb.RDB to enqueues a task from scheduled, retry, dead

queues
This commit is contained in:
Ken Hibino
2019-12-08 06:46:04 -08:00
parent 8e2c4e5716
commit 680a2cf3df
4 changed files with 336 additions and 41 deletions

View File

@@ -2,8 +2,10 @@ package rdb
import (
"encoding/json"
"fmt"
"time"
"github.com/go-redis/redis/v7"
"github.com/google/uuid"
)
@@ -221,3 +223,69 @@ func (r *RDB) ListDead() ([]*DeadTask, error) {
}
return tasks, nil
}
// Rescue finds a task that matches the given id and score from dead queue
// and enqueues it processing. If a task that maches the id and score does
// not exist, it returns ErrTaskNotFound.
func (r *RDB) Rescue(id string, score float64) error {
n, err := r.removeAndEnqueue(deadQ, id, score)
if err != nil {
return err
}
if n == 0 {
return ErrTaskNotFound
}
return nil
}
// RetryNow finds a task that matches the given id and score from retry queue
// and enqueues it for processing. If a task that maches the id and score does
// not exist, it returns ErrTaskNotFound.
func (r *RDB) RetryNow(id string, score float64) error {
n, err := r.removeAndEnqueue(retryQ, id, score)
if err != nil {
return err
}
if n == 0 {
return ErrTaskNotFound
}
return nil
}
// ProcessNow finds a task that matches the given id and score from scheduled queue
// and enqueues it for processing. If a task that maches the id and score does not
// exist, it returns ErrTaskNotFound.
func (r *RDB) ProcessNow(id string, score float64) error {
n, err := r.removeAndEnqueue(scheduledQ, id, score)
if err != nil {
return err
}
if n == 0 {
return ErrTaskNotFound
}
return nil
}
func (r *RDB) removeAndEnqueue(zset, id string, score float64) (int64, error) {
script := redis.NewScript(`
local msgs = redis.call("ZRANGEBYSCORE", KEYS[1], ARGV[1], ARGV[1])
for _, msg in ipairs(msgs) do
local decoded = cjson.decode(msg)
if decoded["ID"] == ARGV[2] then
redis.call("ZREM", KEYS[1], msg)
redis.call("LPUSH", KEYS[2], msg)
return 1
end
end
return 0
`)
res, err := script.Run(r.client, []string{zset, defaultQ}, score, id).Result()
if err != nil {
return 0, err
}
n, ok := res.(int64)
if !ok {
return 0, fmt.Errorf("could not cast %v to int64", res)
}
return n, nil
}