mirror of
https://github.com/hibiken/asynq.git
synced 2025-08-19 15:08:55 +08:00
Add Inspector type
This commit is contained in:
@@ -51,56 +51,6 @@ type DailyStats struct {
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
// EnqueuedTask is a task in a queue and is ready to be processed.
|
||||
type EnqueuedTask struct {
|
||||
ID uuid.UUID
|
||||
Type string
|
||||
Payload map[string]interface{}
|
||||
Queue string
|
||||
}
|
||||
|
||||
// InProgressTask is a task that's currently being processed.
|
||||
type InProgressTask struct {
|
||||
ID uuid.UUID
|
||||
Type string
|
||||
Payload map[string]interface{}
|
||||
}
|
||||
|
||||
// ScheduledTask is a task that's scheduled to be processed in the future.
|
||||
type ScheduledTask struct {
|
||||
ID uuid.UUID
|
||||
Type string
|
||||
Payload map[string]interface{}
|
||||
ProcessAt time.Time
|
||||
Score int64
|
||||
Queue string
|
||||
}
|
||||
|
||||
// RetryTask is a task that's in retry queue because worker failed to process the task.
|
||||
type RetryTask struct {
|
||||
ID uuid.UUID
|
||||
Type string
|
||||
Payload map[string]interface{}
|
||||
// TODO(hibiken): add LastFailedAt time.Time
|
||||
ProcessAt time.Time
|
||||
ErrorMsg string
|
||||
Retried int
|
||||
Retry int
|
||||
Score int64
|
||||
Queue string
|
||||
}
|
||||
|
||||
// DeadTask is a task in that has exhausted all retries.
|
||||
type DeadTask struct {
|
||||
ID uuid.UUID
|
||||
Type string
|
||||
Payload map[string]interface{}
|
||||
LastFailedAt time.Time
|
||||
ErrorMsg string
|
||||
Score int64
|
||||
Queue string
|
||||
}
|
||||
|
||||
// KEYS[1] -> asynq:queues
|
||||
// KEYS[2] -> asynq:in_progress
|
||||
// KEYS[3] -> asynq:scheduled
|
||||
@@ -289,158 +239,79 @@ func (p Pagination) stop() int64 {
|
||||
}
|
||||
|
||||
// ListEnqueued returns enqueued tasks that are ready to be processed.
|
||||
func (r *RDB) ListEnqueued(qname string, pgn Pagination) ([]*EnqueuedTask, error) {
|
||||
func (r *RDB) ListEnqueued(qname string, pgn Pagination) ([]*base.TaskMessage, error) {
|
||||
qkey := base.QueueKey(qname)
|
||||
if !r.client.SIsMember(base.AllQueues, qkey).Val() {
|
||||
return nil, fmt.Errorf("queue %q does not exist", qname)
|
||||
}
|
||||
// Note: Because we use LPUSH to redis list, we need to calculate the
|
||||
// correct range and reverse the list to get the tasks with pagination.
|
||||
stop := -pgn.start() - 1
|
||||
start := -pgn.stop() - 1
|
||||
data, err := r.client.LRange(qkey, start, stop).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reverse(data)
|
||||
var tasks []*EnqueuedTask
|
||||
for _, s := range data {
|
||||
var msg base.TaskMessage
|
||||
err := json.Unmarshal([]byte(s), &msg)
|
||||
if err != nil {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
tasks = append(tasks, &EnqueuedTask{
|
||||
ID: msg.ID,
|
||||
Type: msg.Type,
|
||||
Payload: msg.Payload,
|
||||
Queue: msg.Queue,
|
||||
})
|
||||
}
|
||||
return tasks, nil
|
||||
return r.listMessages(qkey, pgn)
|
||||
}
|
||||
|
||||
// ListInProgress returns all tasks that are currently being processed.
|
||||
func (r *RDB) ListInProgress(pgn Pagination) ([]*InProgressTask, error) {
|
||||
func (r *RDB) ListInProgress(pgn Pagination) ([]*base.TaskMessage, error) {
|
||||
return r.listMessages(base.InProgressQueue, pgn)
|
||||
}
|
||||
|
||||
// listMessages returns a list of TaskMessage in Redis list with the given key.
|
||||
func (r *RDB) listMessages(key string, pgn Pagination) ([]*base.TaskMessage, error) {
|
||||
// Note: Because we use LPUSH to redis list, we need to calculate the
|
||||
// correct range and reverse the list to get the tasks with pagination.
|
||||
stop := -pgn.start() - 1
|
||||
start := -pgn.stop() - 1
|
||||
data, err := r.client.LRange(base.InProgressQueue, start, stop).Result()
|
||||
data, err := r.client.LRange(key, start, stop).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reverse(data)
|
||||
var tasks []*InProgressTask
|
||||
var msgs []*base.TaskMessage
|
||||
for _, s := range data {
|
||||
var msg base.TaskMessage
|
||||
err := json.Unmarshal([]byte(s), &msg)
|
||||
m, err := base.DecodeMessage(s)
|
||||
if err != nil {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
tasks = append(tasks, &InProgressTask{
|
||||
ID: msg.ID,
|
||||
Type: msg.Type,
|
||||
Payload: msg.Payload,
|
||||
})
|
||||
msgs = append(msgs, m)
|
||||
}
|
||||
return tasks, nil
|
||||
return msgs, nil
|
||||
|
||||
}
|
||||
|
||||
// ListScheduled returns all tasks that are scheduled to be processed
|
||||
// in the future.
|
||||
func (r *RDB) ListScheduled(pgn Pagination) ([]*ScheduledTask, error) {
|
||||
data, err := r.client.ZRangeWithScores(base.ScheduledQueue, pgn.start(), pgn.stop()).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tasks []*ScheduledTask
|
||||
for _, z := range data {
|
||||
s, ok := z.Member.(string)
|
||||
if !ok {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
var msg base.TaskMessage
|
||||
err := json.Unmarshal([]byte(s), &msg)
|
||||
if err != nil {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
processAt := time.Unix(int64(z.Score), 0)
|
||||
tasks = append(tasks, &ScheduledTask{
|
||||
ID: msg.ID,
|
||||
Type: msg.Type,
|
||||
Payload: msg.Payload,
|
||||
Queue: msg.Queue,
|
||||
ProcessAt: processAt,
|
||||
Score: int64(z.Score),
|
||||
})
|
||||
}
|
||||
return tasks, nil
|
||||
func (r *RDB) ListScheduled(pgn Pagination) ([]base.Z, error) {
|
||||
return r.listZSetEntries(base.ScheduledQueue, pgn)
|
||||
}
|
||||
|
||||
// ListRetry returns all tasks that have failed before and willl be retried
|
||||
// in the future.
|
||||
func (r *RDB) ListRetry(pgn Pagination) ([]*RetryTask, error) {
|
||||
data, err := r.client.ZRangeWithScores(base.RetryQueue, pgn.start(), pgn.stop()).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tasks []*RetryTask
|
||||
for _, z := range data {
|
||||
s, ok := z.Member.(string)
|
||||
if !ok {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
var msg base.TaskMessage
|
||||
err := json.Unmarshal([]byte(s), &msg)
|
||||
if err != nil {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
processAt := time.Unix(int64(z.Score), 0)
|
||||
tasks = append(tasks, &RetryTask{
|
||||
ID: msg.ID,
|
||||
Type: msg.Type,
|
||||
Payload: msg.Payload,
|
||||
ErrorMsg: msg.ErrorMsg,
|
||||
Retry: msg.Retry,
|
||||
Retried: msg.Retried,
|
||||
Queue: msg.Queue,
|
||||
ProcessAt: processAt,
|
||||
Score: int64(z.Score),
|
||||
})
|
||||
}
|
||||
return tasks, nil
|
||||
func (r *RDB) ListRetry(pgn Pagination) ([]base.Z, error) {
|
||||
return r.listZSetEntries(base.RetryQueue, pgn)
|
||||
}
|
||||
|
||||
// ListDead returns all tasks that have exhausted its retry limit.
|
||||
func (r *RDB) ListDead(pgn Pagination) ([]*DeadTask, error) {
|
||||
data, err := r.client.ZRangeWithScores(base.DeadQueue, pgn.start(), pgn.stop()).Result()
|
||||
func (r *RDB) ListDead(pgn Pagination) ([]base.Z, error) {
|
||||
return r.listZSetEntries(base.DeadQueue, pgn)
|
||||
}
|
||||
|
||||
// listZSetEntries returns a list of message and score pairs in Redis sorted-set
|
||||
// with the given key.
|
||||
func (r *RDB) listZSetEntries(key string, pgn Pagination) ([]base.Z, error) {
|
||||
data, err := r.client.ZRangeWithScores(key, pgn.start(), pgn.stop()).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tasks []*DeadTask
|
||||
var res []base.Z
|
||||
for _, z := range data {
|
||||
s, ok := z.Member.(string)
|
||||
if !ok {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
var msg base.TaskMessage
|
||||
err := json.Unmarshal([]byte(s), &msg)
|
||||
msg, err := base.DecodeMessage(s)
|
||||
if err != nil {
|
||||
continue // bad data, ignore and continue
|
||||
}
|
||||
lastFailedAt := time.Unix(int64(z.Score), 0)
|
||||
tasks = append(tasks, &DeadTask{
|
||||
ID: msg.ID,
|
||||
Type: msg.Type,
|
||||
Payload: msg.Payload,
|
||||
ErrorMsg: msg.ErrorMsg,
|
||||
Queue: msg.Queue,
|
||||
LastFailedAt: lastFailedAt,
|
||||
Score: int64(z.Score),
|
||||
})
|
||||
res = append(res, base.Z{msg, int64(z.Score)})
|
||||
}
|
||||
return tasks, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// EnqueueDeadTask finds a task that matches the given id and score from dead queue
|
||||
@@ -704,19 +575,40 @@ func (r *RDB) deleteTask(zset, id string, score float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAllDeadTasks deletes all tasks from the dead queue.
|
||||
func (r *RDB) DeleteAllDeadTasks() error {
|
||||
return r.client.Del(base.DeadQueue).Err()
|
||||
// KEYS[1] -> queue to delete
|
||||
var deleteAllCmd = redis.NewScript(`
|
||||
local n = redis.call("ZCARD", KEYS[1])
|
||||
redis.call("DEL", KEYS[1])
|
||||
return n`)
|
||||
|
||||
// DeleteAllDeadTasks deletes all tasks from the dead queue
|
||||
// and returns the number of tasks deleted.
|
||||
func (r *RDB) DeleteAllDeadTasks() (int64, error) {
|
||||
return r.deleteAll(base.DeadQueue)
|
||||
}
|
||||
|
||||
// DeleteAllRetryTasks deletes all tasks from the dead queue.
|
||||
func (r *RDB) DeleteAllRetryTasks() error {
|
||||
return r.client.Del(base.RetryQueue).Err()
|
||||
// DeleteAllRetryTasks deletes all tasks from the dead queue
|
||||
// and returns the number of tasks deleted.
|
||||
func (r *RDB) DeleteAllRetryTasks() (int64, error) {
|
||||
return r.deleteAll(base.RetryQueue)
|
||||
}
|
||||
|
||||
// DeleteAllScheduledTasks deletes all tasks from the dead queue.
|
||||
func (r *RDB) DeleteAllScheduledTasks() error {
|
||||
return r.client.Del(base.ScheduledQueue).Err()
|
||||
// DeleteAllScheduledTasks deletes all tasks from the dead queue
|
||||
// and returns the number of tasks deleted.
|
||||
func (r *RDB) DeleteAllScheduledTasks() (int64, error) {
|
||||
return r.deleteAll(base.ScheduledQueue)
|
||||
}
|
||||
|
||||
func (r *RDB) deleteAll(key string) (int64, error) {
|
||||
res, err := deleteAllCmd.Run(r.client, []string{key}).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
|
||||
}
|
||||
|
||||
// ErrQueueNotFound indicates specified queue does not exist.
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -148,7 +148,7 @@ func TestDequeue(t *testing.T) {
|
||||
err error
|
||||
wantEnqueued map[string][]*base.TaskMessage
|
||||
wantInProgress []*base.TaskMessage
|
||||
wantDeadlines []h.ZSetEntry
|
||||
wantDeadlines []base.Z
|
||||
}{
|
||||
{
|
||||
enqueued: map[string][]*base.TaskMessage{
|
||||
@@ -162,10 +162,10 @@ func TestDequeue(t *testing.T) {
|
||||
"default": {},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{t1},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
wantDeadlines: []base.Z{
|
||||
{
|
||||
Msg: t1,
|
||||
Score: float64(t1Deadline),
|
||||
Message: t1,
|
||||
Score: t1Deadline,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -181,7 +181,7 @@ func TestDequeue(t *testing.T) {
|
||||
"default": {},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{},
|
||||
wantDeadlines: []h.ZSetEntry{},
|
||||
wantDeadlines: []base.Z{},
|
||||
},
|
||||
{
|
||||
enqueued: map[string][]*base.TaskMessage{
|
||||
@@ -199,10 +199,10 @@ func TestDequeue(t *testing.T) {
|
||||
"low": {t3},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
wantDeadlines: []base.Z{
|
||||
{
|
||||
Msg: t2,
|
||||
Score: float64(t2Deadline),
|
||||
Message: t2,
|
||||
Score: t2Deadline,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -222,10 +222,10 @@ func TestDequeue(t *testing.T) {
|
||||
"low": {t2, t1},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{t3},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
wantDeadlines: []base.Z{
|
||||
{
|
||||
Msg: t3,
|
||||
Score: float64(t3Deadline),
|
||||
Message: t3,
|
||||
Score: t3Deadline,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -245,7 +245,7 @@ func TestDequeue(t *testing.T) {
|
||||
"low": {},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{},
|
||||
wantDeadlines: []h.ZSetEntry{},
|
||||
wantDeadlines: []base.Z{},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -412,70 +412,70 @@ func TestDone(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
inProgress []*base.TaskMessage // initial state of the in-progress list
|
||||
deadlines []h.ZSetEntry // initial state of deadlines set
|
||||
deadlines []base.Z // initial state of deadlines set
|
||||
target *base.TaskMessage // task to remove
|
||||
wantInProgress []*base.TaskMessage // final state of the in-progress list
|
||||
wantDeadlines []h.ZSetEntry // final state of the deadline set
|
||||
wantDeadlines []base.Z // final state of the deadline set
|
||||
}{
|
||||
{
|
||||
inProgress: []*base.TaskMessage{t1, t2},
|
||||
deadlines: []h.ZSetEntry{
|
||||
deadlines: []base.Z{
|
||||
{
|
||||
Msg: t1,
|
||||
Score: float64(t1Deadline),
|
||||
Message: t1,
|
||||
Score: t1Deadline,
|
||||
},
|
||||
{
|
||||
Msg: t2,
|
||||
Score: float64(t2Deadline),
|
||||
Message: t2,
|
||||
Score: t2Deadline,
|
||||
},
|
||||
},
|
||||
target: t1,
|
||||
wantInProgress: []*base.TaskMessage{t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
wantDeadlines: []base.Z{
|
||||
{
|
||||
Msg: t2,
|
||||
Score: float64(t2Deadline),
|
||||
Message: t2,
|
||||
Score: t2Deadline,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
inProgress: []*base.TaskMessage{t1},
|
||||
deadlines: []h.ZSetEntry{
|
||||
deadlines: []base.Z{
|
||||
{
|
||||
Msg: t1,
|
||||
Score: float64(t1Deadline),
|
||||
Message: t1,
|
||||
Score: t1Deadline,
|
||||
},
|
||||
},
|
||||
target: t1,
|
||||
wantInProgress: []*base.TaskMessage{},
|
||||
wantDeadlines: []h.ZSetEntry{},
|
||||
wantDeadlines: []base.Z{},
|
||||
},
|
||||
{
|
||||
inProgress: []*base.TaskMessage{t1, t2, t3},
|
||||
deadlines: []h.ZSetEntry{
|
||||
deadlines: []base.Z{
|
||||
{
|
||||
Msg: t1,
|
||||
Score: float64(t1Deadline),
|
||||
Message: t1,
|
||||
Score: t1Deadline,
|
||||
},
|
||||
{
|
||||
Msg: t2,
|
||||
Score: float64(t2Deadline),
|
||||
Message: t2,
|
||||
Score: t2Deadline,
|
||||
},
|
||||
{
|
||||
Msg: t3,
|
||||
Score: float64(t3Deadline),
|
||||
Message: t3,
|
||||
Score: t3Deadline,
|
||||
},
|
||||
},
|
||||
target: t3,
|
||||
wantInProgress: []*base.TaskMessage{t1, t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
wantDeadlines: []base.Z{
|
||||
{
|
||||
Msg: t1,
|
||||
Score: float64(t1Deadline),
|
||||
Message: t1,
|
||||
Score: t1Deadline,
|
||||
},
|
||||
{
|
||||
Msg: t2,
|
||||
Score: float64(t2Deadline),
|
||||
Message: t2,
|
||||
Score: t2Deadline,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -560,28 +560,28 @@ func TestRequeue(t *testing.T) {
|
||||
tests := []struct {
|
||||
enqueued map[string][]*base.TaskMessage // initial state of queues
|
||||
inProgress []*base.TaskMessage // initial state of the in-progress list
|
||||
deadlines []h.ZSetEntry // initial state of the deadlines set
|
||||
deadlines []base.Z // initial state of the deadlines set
|
||||
target *base.TaskMessage // task to requeue
|
||||
wantEnqueued map[string][]*base.TaskMessage // final state of queues
|
||||
wantInProgress []*base.TaskMessage // final state of the in-progress list
|
||||
wantDeadlines []h.ZSetEntry // final state of the deadlines set
|
||||
wantDeadlines []base.Z // final state of the deadlines set
|
||||
}{
|
||||
{
|
||||
enqueued: map[string][]*base.TaskMessage{
|
||||
base.DefaultQueueName: {},
|
||||
},
|
||||
inProgress: []*base.TaskMessage{t1, t2},
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(t1Deadline)},
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: t1Deadline},
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
target: t1,
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
base.DefaultQueueName: {t1},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
wantDeadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -589,15 +589,15 @@ func TestRequeue(t *testing.T) {
|
||||
base.DefaultQueueName: {t1},
|
||||
},
|
||||
inProgress: []*base.TaskMessage{t2},
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
deadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
target: t2,
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
base.DefaultQueueName: {t1, t2},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{},
|
||||
wantDeadlines: []h.ZSetEntry{},
|
||||
wantDeadlines: []base.Z{},
|
||||
},
|
||||
{
|
||||
enqueued: map[string][]*base.TaskMessage{
|
||||
@@ -605,9 +605,9 @@ func TestRequeue(t *testing.T) {
|
||||
"critical": {},
|
||||
},
|
||||
inProgress: []*base.TaskMessage{t2, t3},
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
{Msg: t3, Score: float64(t3Deadline)},
|
||||
deadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
{Message: t3, Score: t3Deadline},
|
||||
},
|
||||
target: t3,
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
@@ -615,8 +615,8 @@ func TestRequeue(t *testing.T) {
|
||||
"critical": {t3},
|
||||
},
|
||||
wantInProgress: []*base.TaskMessage{t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
wantDeadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -765,42 +765,42 @@ func TestRetry(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
inProgress []*base.TaskMessage
|
||||
deadlines []h.ZSetEntry
|
||||
retry []h.ZSetEntry
|
||||
deadlines []base.Z
|
||||
retry []base.Z
|
||||
msg *base.TaskMessage
|
||||
processAt time.Time
|
||||
errMsg string
|
||||
wantInProgress []*base.TaskMessage
|
||||
wantDeadlines []h.ZSetEntry
|
||||
wantRetry []h.ZSetEntry
|
||||
wantDeadlines []base.Z
|
||||
wantRetry []base.Z
|
||||
}{
|
||||
{
|
||||
inProgress: []*base.TaskMessage{t1, t2},
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(t1Deadline)},
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: t1Deadline},
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
retry: []h.ZSetEntry{
|
||||
retry: []base.Z{
|
||||
{
|
||||
Msg: t3,
|
||||
Score: float64(now.Add(time.Minute).Unix()),
|
||||
Message: t3,
|
||||
Score: now.Add(time.Minute).Unix(),
|
||||
},
|
||||
},
|
||||
msg: t1,
|
||||
processAt: now.Add(5 * time.Minute),
|
||||
errMsg: errMsg,
|
||||
wantInProgress: []*base.TaskMessage{t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
wantDeadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
wantRetry: []h.ZSetEntry{
|
||||
wantRetry: []base.Z{
|
||||
{
|
||||
Msg: h.TaskMessageAfterRetry(*t1, errMsg),
|
||||
Score: float64(now.Add(5 * time.Minute).Unix()),
|
||||
Message: h.TaskMessageAfterRetry(*t1, errMsg),
|
||||
Score: now.Add(5 * time.Minute).Unix(),
|
||||
},
|
||||
{
|
||||
Msg: t3,
|
||||
Score: float64(now.Add(time.Minute).Unix()),
|
||||
Message: t3,
|
||||
Score: now.Add(time.Minute).Unix(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -891,59 +891,59 @@ func TestKill(t *testing.T) {
|
||||
// TODO(hibiken): add test cases for trimming
|
||||
tests := []struct {
|
||||
inProgress []*base.TaskMessage
|
||||
deadlines []h.ZSetEntry
|
||||
dead []h.ZSetEntry
|
||||
deadlines []base.Z
|
||||
dead []base.Z
|
||||
target *base.TaskMessage // task to kill
|
||||
wantInProgress []*base.TaskMessage
|
||||
wantDeadlines []h.ZSetEntry
|
||||
wantDead []h.ZSetEntry
|
||||
wantDeadlines []base.Z
|
||||
wantDead []base.Z
|
||||
}{
|
||||
{
|
||||
inProgress: []*base.TaskMessage{t1, t2},
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(t1Deadline)},
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: t1Deadline},
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
dead: []h.ZSetEntry{
|
||||
dead: []base.Z{
|
||||
{
|
||||
Msg: t3,
|
||||
Score: float64(now.Add(-time.Hour).Unix()),
|
||||
Message: t3,
|
||||
Score: now.Add(-time.Hour).Unix(),
|
||||
},
|
||||
},
|
||||
target: t1,
|
||||
wantInProgress: []*base.TaskMessage{t2},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
wantDeadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
},
|
||||
wantDead: []h.ZSetEntry{
|
||||
wantDead: []base.Z{
|
||||
{
|
||||
Msg: h.TaskMessageWithError(*t1, errMsg),
|
||||
Score: float64(now.Unix()),
|
||||
Message: h.TaskMessageWithError(*t1, errMsg),
|
||||
Score: now.Unix(),
|
||||
},
|
||||
{
|
||||
Msg: t3,
|
||||
Score: float64(now.Add(-time.Hour).Unix()),
|
||||
Message: t3,
|
||||
Score: now.Add(-time.Hour).Unix(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
inProgress: []*base.TaskMessage{t1, t2, t3},
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(t1Deadline)},
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
{Msg: t3, Score: float64(t3Deadline)},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: t1Deadline},
|
||||
{Message: t2, Score: t2Deadline},
|
||||
{Message: t3, Score: t3Deadline},
|
||||
},
|
||||
dead: []h.ZSetEntry{},
|
||||
dead: []base.Z{},
|
||||
target: t1,
|
||||
wantInProgress: []*base.TaskMessage{t2, t3},
|
||||
wantDeadlines: []h.ZSetEntry{
|
||||
{Msg: t2, Score: float64(t2Deadline)},
|
||||
{Msg: t3, Score: float64(t3Deadline)},
|
||||
wantDeadlines: []base.Z{
|
||||
{Message: t2, Score: t2Deadline},
|
||||
{Message: t3, Score: t3Deadline},
|
||||
},
|
||||
wantDead: []h.ZSetEntry{
|
||||
wantDead: []base.Z{
|
||||
{
|
||||
Msg: h.TaskMessageWithError(*t1, errMsg),
|
||||
Score: float64(now.Unix()),
|
||||
Message: h.TaskMessageWithError(*t1, errMsg),
|
||||
Score: now.Unix(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1009,19 +1009,19 @@ func TestCheckAndEnqueue(t *testing.T) {
|
||||
hourFromNow := time.Now().Add(time.Hour)
|
||||
|
||||
tests := []struct {
|
||||
scheduled []h.ZSetEntry
|
||||
retry []h.ZSetEntry
|
||||
scheduled []base.Z
|
||||
retry []base.Z
|
||||
wantEnqueued map[string][]*base.TaskMessage
|
||||
wantScheduled []*base.TaskMessage
|
||||
wantRetry []*base.TaskMessage
|
||||
}{
|
||||
{
|
||||
scheduled: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(secondAgo.Unix())},
|
||||
{Msg: t2, Score: float64(secondAgo.Unix())},
|
||||
scheduled: []base.Z{
|
||||
{Message: t1, Score: secondAgo.Unix()},
|
||||
{Message: t2, Score: secondAgo.Unix()},
|
||||
},
|
||||
retry: []h.ZSetEntry{
|
||||
{Msg: t3, Score: float64(secondAgo.Unix())}},
|
||||
retry: []base.Z{
|
||||
{Message: t3, Score: secondAgo.Unix()}},
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
"default": {t1, t2, t3},
|
||||
},
|
||||
@@ -1029,11 +1029,11 @@ func TestCheckAndEnqueue(t *testing.T) {
|
||||
wantRetry: []*base.TaskMessage{},
|
||||
},
|
||||
{
|
||||
scheduled: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(hourFromNow.Unix())},
|
||||
{Msg: t2, Score: float64(secondAgo.Unix())}},
|
||||
retry: []h.ZSetEntry{
|
||||
{Msg: t3, Score: float64(secondAgo.Unix())}},
|
||||
scheduled: []base.Z{
|
||||
{Message: t1, Score: hourFromNow.Unix()},
|
||||
{Message: t2, Score: secondAgo.Unix()}},
|
||||
retry: []base.Z{
|
||||
{Message: t3, Score: secondAgo.Unix()}},
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
"default": {t2, t3},
|
||||
},
|
||||
@@ -1041,11 +1041,11 @@ func TestCheckAndEnqueue(t *testing.T) {
|
||||
wantRetry: []*base.TaskMessage{},
|
||||
},
|
||||
{
|
||||
scheduled: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(hourFromNow.Unix())},
|
||||
{Msg: t2, Score: float64(hourFromNow.Unix())}},
|
||||
retry: []h.ZSetEntry{
|
||||
{Msg: t3, Score: float64(hourFromNow.Unix())}},
|
||||
scheduled: []base.Z{
|
||||
{Message: t1, Score: hourFromNow.Unix()},
|
||||
{Message: t2, Score: hourFromNow.Unix()}},
|
||||
retry: []base.Z{
|
||||
{Message: t3, Score: hourFromNow.Unix()}},
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
"default": {},
|
||||
},
|
||||
@@ -1053,12 +1053,12 @@ func TestCheckAndEnqueue(t *testing.T) {
|
||||
wantRetry: []*base.TaskMessage{t3},
|
||||
},
|
||||
{
|
||||
scheduled: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(secondAgo.Unix())},
|
||||
{Msg: t4, Score: float64(secondAgo.Unix())},
|
||||
scheduled: []base.Z{
|
||||
{Message: t1, Score: secondAgo.Unix()},
|
||||
{Message: t4, Score: secondAgo.Unix()},
|
||||
},
|
||||
retry: []h.ZSetEntry{
|
||||
{Msg: t5, Score: float64(secondAgo.Unix())}},
|
||||
retry: []base.Z{
|
||||
{Message: t5, Score: secondAgo.Unix()}},
|
||||
wantEnqueued: map[string][]*base.TaskMessage{
|
||||
"default": {t1},
|
||||
"critical": {t4},
|
||||
@@ -1112,41 +1112,41 @@ func TestListDeadlineExceeded(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
deadlines []h.ZSetEntry
|
||||
deadlines []base.Z
|
||||
t time.Time
|
||||
want []*base.TaskMessage
|
||||
}{
|
||||
{
|
||||
desc: "with one task in-progress",
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(fiveMinutesAgo.Unix())},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: fiveMinutesAgo.Unix()},
|
||||
},
|
||||
t: time.Now(),
|
||||
want: []*base.TaskMessage{t1},
|
||||
},
|
||||
{
|
||||
desc: "with multiple tasks in-progress, and one expired",
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(oneHourAgo.Unix())},
|
||||
{Msg: t2, Score: float64(fiveMinutesFromNow.Unix())},
|
||||
{Msg: t3, Score: float64(oneHourFromNow.Unix())},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: oneHourAgo.Unix()},
|
||||
{Message: t2, Score: fiveMinutesFromNow.Unix()},
|
||||
{Message: t3, Score: oneHourFromNow.Unix()},
|
||||
},
|
||||
t: time.Now(),
|
||||
want: []*base.TaskMessage{t1},
|
||||
},
|
||||
{
|
||||
desc: "with multiple expired tasks in-progress",
|
||||
deadlines: []h.ZSetEntry{
|
||||
{Msg: t1, Score: float64(oneHourAgo.Unix())},
|
||||
{Msg: t2, Score: float64(fiveMinutesAgo.Unix())},
|
||||
{Msg: t3, Score: float64(oneHourFromNow.Unix())},
|
||||
deadlines: []base.Z{
|
||||
{Message: t1, Score: oneHourAgo.Unix()},
|
||||
{Message: t2, Score: fiveMinutesAgo.Unix()},
|
||||
{Message: t3, Score: oneHourFromNow.Unix()},
|
||||
},
|
||||
t: time.Now(),
|
||||
want: []*base.TaskMessage{t1, t2},
|
||||
},
|
||||
{
|
||||
desc: "with empty in-progress queue",
|
||||
deadlines: []h.ZSetEntry{},
|
||||
deadlines: []base.Z{},
|
||||
t: time.Now(),
|
||||
want: []*base.TaskMessage{},
|
||||
},
|
||||
|
Reference in New Issue
Block a user