Beispiel #1
0
func TestConfig(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	config := disque.Config{
		Timeout: time.Millisecond,
	}

	// Should fail on timeout.
	_, err = jobs.With(config).Get("test:non-existant-queue")
	if err == nil {
		t.Fatal("expected error")
	}

	// Should fail on timeout.
	jobs.Use(config)
	_, err = jobs.Get("test:non-existant-queue")
	if err == nil {
		t.Fatal("expected error")
	}
}
Beispiel #2
0
func TestDelay(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	// Enqueue job after one second.
	_, err = jobs.Delay(time.Second).Add("data1", "test:delay")
	if err != nil {
		t.Error(err)
	}

	// The job should not exist yet.
	_, err = jobs.Timeout(time.Millisecond).Get("test:delay")
	if err == nil {
		t.Fatal("expected error")
	}

	time.Sleep(time.Second)

	// The job should exist now.
	job, err := jobs.Timeout(500 * time.Millisecond).Get("test:delay")
	if err != nil {
		t.Fatal(err)
	}

	jobs.Ack(job)
}
Beispiel #3
0
func TestWait(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	// Enqueue job.
	start := time.Now()
	job, err := jobs.Add("data1", "test:wait")
	if err != nil {
		t.Error(err)
	}

	go func() {
		// Get the job.
		job, err := jobs.Get("test:wait")
		if err != nil {
			t.Fatal(err)
		}

		// Sleep for 1 second before ACK.
		time.Sleep(time.Second)
		jobs.Ack(job)

	}()

	// Wait for the job to finish. Should take more than 1 second.
	jobs.Wait(job)
	duration := time.Since(start)
	if duration < time.Second || duration > 1500*time.Millisecond {
		t.Fatalf("expected 1.0s - 1.5s, got %v", time.Since(start))
	}
}
Beispiel #4
0
func TestQueueLength(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	var length int

	// Make sure 0 jobs are enqueued.
	length, err = jobs.Len("test:len")
	if err != nil {
		t.Error(err)
	}
	if length != 0 {
		t.Error("unexpected length %v", length)
	}

	// Enqueue hundred jobs.
	for i := 0; i < 100; i++ {
		_, err = jobs.Add("data1", "test:len")
		if err != nil {
			t.Error(err)
		}
	}

	// Make sure 100 jobs are enqueued.
	length, err = jobs.Len("test:len")
	if err != nil {
		t.Error(err)
	}
	if length != 100 {
		t.Error("unexpected length %v", length)
	}

	// Dequeue hundred jobs.
	for i := 0; i < 100; i++ {
		job, err := jobs.Get("test:len")
		if err != nil {
			t.Error(err)
		}
		jobs.Ack(job)
	}

	// Make sure 0 jobs are enqueued.
	length, err = jobs.Len("test:len")
	if err != nil {
		t.Error(err)
	}
	if length != 0 {
		t.Error("unexpected length %v", length)
	}
}
Beispiel #5
0
func New(conf *config.Config) (*Qmd, error) {
	db, err := NewDB(conf.DB.RedisURI)
	if err != nil {
		return nil, err
	}

	if err := db.Ping(); err != nil {
		return nil, err
	}

	queue, err := disque.New(conf.Queue.DisqueURI)
	if err != nil {
		return nil, err
	}
	queue.Use(disque.Config{
		RetryAfter: time.Duration(conf.MaxExecTime) * time.Second,
		Timeout:    time.Second,
	})

	if err := queue.Ping(); err != nil {
		return nil, err
	}

	// TODO: SlackNOP.
	slack := &SlackNotifier{
		WebhookURL: conf.Slack.WebhookURL,
		Channel:    conf.Slack.Channel,
		Prefix:     fmt.Sprintf("%v: ", conf.URL),
	}

	qmd := &Qmd{
		Config:             conf,
		DB:                 db,
		Queue:              queue,
		Workers:            make(chan Worker, conf.MaxJobs),
		ClosingListenQueue: make(chan struct{}),
		ClosingWorkers:     make(chan struct{}),
		Slack:              slack,
	}

	if err := lg.SetLevelString("debug"); err != nil {
		return nil, err
	}

	lg.AlertFn = func(level lg.Level, msg string) {
		switch level {
		case lg.ErrorLevel, lg.FatalLevel, lg.PanicLevel:
			qmd.Slack.Notify(msg)
		}
	}

	return qmd, nil
}
Beispiel #6
0
func TestPing(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	// Ping.
	if jobs.Ping() != nil {
		t.Fatal(err)
	}
}
Beispiel #7
0
func TestTimeoutRetryAfter(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	// Enqueue job with retry after one second.
	_, err = jobs.RetryAfter(time.Second).Add("data1", "test:retry")
	if err != nil {
		t.Error(err)
	}

	// Get the job.
	_, err = jobs.Get("test:retry")
	if err != nil {
		t.Fatal(err)
	}

	// Don't Ack() to pretend consumer failure.

	// Try to get the job again..
	// We should hit time-out for the first time..
	_, err = jobs.Timeout(250 * time.Millisecond).Get("test:retry")
	if err == nil {
		t.Fatal("expected error")
	}
	// and we should be successful for the second time..
	job, err := jobs.Timeout(time.Second).Get("test:retry")
	if err != nil {
		t.Fatal(err)
	}

	// Ack the job.
	err = jobs.Ack(job)
	if err != nil {
		t.Fatal(err)
	}
}
Beispiel #8
0
func TestTTL(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	// Enqueue job with TTL one second.
	_, err = jobs.Timeout(time.Millisecond).TTL(time.Second).Add("data1", "test:ttl")
	if err != nil {
		t.Error(err)
	}

	time.Sleep(1500 * time.Millisecond)

	// The job should no longer exist.
	_, err = jobs.Get("test:ttl")
	if err == nil {
		t.Fatal("expected error")
	}
}
Beispiel #9
0
// NewDisqueCluster creates disque connection pools to the cluster using hosts information
func NewDisqueCluster(config *DisqueClusterConfig) (*DisqueCluster, error) {
	var lbMode DisqueClusterLBMode
	if config.LBMode > 0 {
		lbMode = config.LBMode
	} else {
		lbMode = DisqueClusterLBModeRoundRobin
	}
	cluster := &DisqueCluster{
		config: config,
		lbMode: lbMode,
	}
	n := len(config.Hosts)
	pools := make([]*disque.Pool, n, n)
	for i, host := range config.Hosts {
		pool, err := disque.New(host["address"].(string))
		if err != nil {
			return nil, err
		}
		pools[i] = pool
	}
	cluster.pools = pools
	cluster.poolIndex = 0
	return cluster, nil
}
Beispiel #10
0
func TestPriorityQueue(t *testing.T) {
	// Connect to Disque.
	jobs, err := disque.New("127.0.0.1:7711")
	if err != nil {
		t.Fatal(err)
	}
	defer jobs.Close()

	// Enqueue three jobs.
	_, err = jobs.Add("data1", "test:low")
	if err != nil {
		t.Error(err)
	}
	_, err = jobs.Add("data2", "test:urgent")
	if err != nil {
		t.Error(err)
	}
	_, err = jobs.Add("data3", "test:high")
	if err != nil {
		t.Error(err)
	}

	// Get first job.
	job, err := jobs.Get("test:urgent", "test:high", "test:low")
	if err != nil {
		t.Fatal(err)
	}
	err = jobs.Ack(job)
	if err != nil {
		t.Fatal(err)
	}
	if e := "test:urgent"; job.Queue != e {
		t.Fatalf("expected %s, got %s", e, job.Queue)
	}
	if e := "data2"; job.Data != e {
		t.Fatalf("expected %s, got %s", e, job.Data)
	}

	// Get second job.
	job, err = jobs.Get("test:urgent", "test:high", "test:low")
	if err != nil {
		t.Fatal(err)
	}
	err = jobs.Ack(job)
	if err != nil {
		t.Fatal(err)
	}
	if e := "test:high"; job.Queue != e {
		t.Fatalf("expected %s, got %s", e, job.Queue)
	}
	if e := "data3"; job.Data != e {
		t.Fatalf("expected %s, got %s", e, job.Data)
	}

	// Get third job and re-queue it again.
	job, err = jobs.Get("test:urgent", "test:high", "test:low")
	if err != nil {
		t.Fatal(err)
	}
	err = jobs.Nack(job)
	if err != nil {
		t.Fatal(err)
	}
	if e := "test:low"; job.Queue != e {
		t.Fatalf("expected %s, got %s", e, job.Queue)
	}
	if e := "data1"; job.Data != e {
		t.Fatalf("expected %s, got %s", e, job.Data)
	}

	// Get third job again.
	job, err = jobs.Get("test:urgent", "test:high", "test:low")
	if err != nil {
		t.Fatal(err)
	}
	err = jobs.Ack(job)
	if err != nil {
		t.Fatal(err)
	}
	if e := "test:low"; job.Queue != e {
		t.Fatalf("expected %s, got %s", e, job.Queue)
	}
	if e := "data1"; job.Data != e {
		t.Fatalf("expected %s, got %s", e, job.Data)
	}
}