2020-01-18 23:32:06 +08:00
|
|
|
// Copyright 2020 Kentaro Hibino. All rights reserved.
|
|
|
|
// Use of this source code is governed by a MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package asynq
|
|
|
|
|
|
|
|
import (
|
2020-02-16 15:14:30 +08:00
|
|
|
"sync"
|
2020-01-18 23:32:06 +08:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-redis/redis/v7"
|
|
|
|
h "github.com/hibiken/asynq/internal/asynqtest"
|
|
|
|
"github.com/hibiken/asynq/internal/base"
|
|
|
|
"github.com/hibiken/asynq/internal/rdb"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestSyncer(t *testing.T) {
|
|
|
|
inProgress := []*base.TaskMessage{
|
|
|
|
h.NewTaskMessage("send_email", nil),
|
|
|
|
h.NewTaskMessage("reindex", nil),
|
|
|
|
h.NewTaskMessage("gen_thumbnail", nil),
|
|
|
|
}
|
|
|
|
r := setup(t)
|
|
|
|
rdbClient := rdb.NewRDB(r)
|
|
|
|
h.SeedInProgressQueue(t, r, inProgress)
|
|
|
|
|
|
|
|
const interval = time.Second
|
|
|
|
syncRequestCh := make(chan *syncRequest)
|
|
|
|
syncer := newSyncer(syncRequestCh, interval)
|
2020-02-16 15:14:30 +08:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
syncer.start(&wg)
|
2020-01-18 23:32:06 +08:00
|
|
|
defer syncer.terminate()
|
|
|
|
|
|
|
|
for _, msg := range inProgress {
|
|
|
|
m := msg
|
|
|
|
syncRequestCh <- &syncRequest{
|
|
|
|
fn: func() error {
|
|
|
|
return rdbClient.Done(m)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-19 02:17:39 +08:00
|
|
|
time.Sleep(2 * interval) // ensure that syncer runs at least once
|
2020-01-18 23:32:06 +08:00
|
|
|
|
|
|
|
gotInProgress := h.GetInProgressMessages(t, r)
|
|
|
|
if l := len(gotInProgress); l != 0 {
|
|
|
|
t.Errorf("%q has length %d; want 0", base.InProgressQueue, l)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSyncerRetry(t *testing.T) {
|
|
|
|
inProgress := []*base.TaskMessage{
|
|
|
|
h.NewTaskMessage("send_email", nil),
|
|
|
|
h.NewTaskMessage("reindex", nil),
|
|
|
|
h.NewTaskMessage("gen_thumbnail", nil),
|
|
|
|
}
|
|
|
|
goodClient := setup(t)
|
|
|
|
h.SeedInProgressQueue(t, goodClient, inProgress)
|
|
|
|
|
|
|
|
// Simulate the situation where redis server is down
|
|
|
|
// by connecting to a wrong port.
|
|
|
|
badClient := redis.NewClient(&redis.Options{
|
|
|
|
Addr: "localhost:6390",
|
|
|
|
})
|
|
|
|
rdbClient := rdb.NewRDB(badClient)
|
|
|
|
|
|
|
|
const interval = time.Second
|
|
|
|
syncRequestCh := make(chan *syncRequest)
|
|
|
|
syncer := newSyncer(syncRequestCh, interval)
|
2020-02-16 15:14:30 +08:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
syncer.start(&wg)
|
2020-01-18 23:32:06 +08:00
|
|
|
defer syncer.terminate()
|
|
|
|
|
|
|
|
for _, msg := range inProgress {
|
|
|
|
m := msg
|
|
|
|
syncRequestCh <- &syncRequest{
|
|
|
|
fn: func() error {
|
|
|
|
return rdbClient.Done(m)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-19 02:17:39 +08:00
|
|
|
time.Sleep(2 * interval) // ensure that syncer runs at least once
|
2020-01-18 23:32:06 +08:00
|
|
|
|
|
|
|
// Sanity check to ensure that message was not successfully deleted
|
|
|
|
// from in-progress list.
|
|
|
|
gotInProgress := h.GetInProgressMessages(t, goodClient)
|
|
|
|
if l := len(gotInProgress); l != len(inProgress) {
|
|
|
|
t.Errorf("%q has length %d; want %d", base.InProgressQueue, l, len(inProgress))
|
|
|
|
}
|
|
|
|
|
2020-01-31 22:48:58 +08:00
|
|
|
// FIXME: This assignment introduces data race and running the test with -race will fail.
|
2020-01-18 23:32:06 +08:00
|
|
|
// simualate failover.
|
|
|
|
rdbClient = rdb.NewRDB(goodClient)
|
|
|
|
|
2020-01-19 02:17:39 +08:00
|
|
|
time.Sleep(2 * interval) // ensure that syncer runs at least once
|
2020-01-18 23:32:06 +08:00
|
|
|
|
|
|
|
gotInProgress = h.GetInProgressMessages(t, goodClient)
|
|
|
|
if l := len(gotInProgress); l != 0 {
|
|
|
|
t.Errorf("%q has length %d; want 0", base.InProgressQueue, l)
|
|
|
|
}
|
|
|
|
}
|