From b644a1c2e39a5a6b399214e7a3212a3d8a806ee3 Mon Sep 17 00:00:00 2001 From: ardhi Date: Fri, 18 Sep 2020 12:24:44 +0700 Subject: [PATCH 1/7] Add Makefile and fix the linter errors --- .gitignore | 2 + Makefile | 31 ++ benches/bench_goworker/main.go | 28 +- benches/bench_goworkers/main.go | 27 +- benches/bench_jobs/main.go | 27 +- benches/bench_work/main.go | 28 +- client_test.go | 63 +-- cmd/workfakedata/main.go | 10 +- cmd/workwebui/main.go | 3 +- dead_pool_reaper.go | 10 +- dead_pool_reaper_test.go | 12 +- enqueue_test.go | 53 +-- etc/out/profile.cov | 731 ++++++++++++++++++++++++++++++++ go.mod | 2 - go.sum | 5 +- heartbeater.go | 2 +- heartbeater_test.go | 2 +- observer.go | 2 +- observer_test.go | 8 +- periodic_enqueuer.go | 33 +- periodic_enqueuer_test.go | 4 +- priority_sampler.go | 12 +- requeuer.go | 2 +- requeuer_test.go | 4 +- run.go | 4 +- time.go | 5 - webui/webui_test.go | 26 +- worker.go | 16 +- worker_pool.go | 2 +- worker_pool_test.go | 13 +- worker_test.go | 38 +- 31 files changed, 972 insertions(+), 233 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 etc/out/profile.cov diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..671b433b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +etc/out/ +vendor/ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..210fa52d --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +SHELL := bash +.SHELLFLAGS := -eu -o pipefail -c +.PHONY: all + + +all: setup build test lint + +setup: + if [ ! -e $(shell go env GOPATH)/bin/golangci-lint ] ; then curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.31.0 ; fi; + +build: + go build ./... + +dep: + go mod tidy + +lint: + golangci-lint run --disable-all \ + --enable=staticcheck --enable=unused --enable=gosimple --enable=structcheck --enable=varcheck --enable=ineffassign \ + --enable=deadcode --enable=typecheck --enable=stylecheck --enable=gosec --enable=unconvert --enable=gofmt \ + --enable=unparam --enable=nakedret --enable=gochecknoinits --enable=depguard --enable=gocyclo --enable=misspell \ + --enable=megacheck --enable=goimports --enable=golint \ + --deadline=5m --no-config + +lint-strict: + golangci-lint run --enable-all + +test: + mkdir -p ./etc/out + ENVIRONMENT=test go test -failfast -count 1 -timeout 30s -race -covermode=atomic -coverprofile=etc/out/profile.cov ./... && go tool cover -func=etc/out/profile.cov + diff --git a/benches/bench_goworker/main.go b/benches/bench_goworker/main.go index e254d6f1..faf41356 100644 --- a/benches/bench_goworker/main.go +++ b/benches/bench_goworker/main.go @@ -55,23 +55,21 @@ func monitor() { prev := int64(0) DALOOP: - for { - select { - case <-t: - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v + for range t { + curT++ + v := atomic.AddInt64(&totcount, 0) + fmt.Printf("after %d seconds, count is %d\n", curT, v) + if curT == 1 { + c1 = v + } else if curT == 3 { + c2 = v } + if v == prev { + break DALOOP + } + prev = v } + fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) os.Exit(0) } diff --git a/benches/bench_goworkers/main.go b/benches/bench_goworkers/main.go index 153d4874..6e51df7c 100644 --- a/benches/bench_goworkers/main.go +++ b/benches/bench_goworkers/main.go @@ -67,23 +67,20 @@ func monitor() { prev := int64(0) DALOOP: - for { - select { - case <-t: - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v + for range t { + curT++ + v := atomic.AddInt64(&totcount, 0) + fmt.Printf("after %d seconds, count is %d\n", curT, v) + if curT == 1 { + c1 = v + } else if curT == 3 { + c2 = v + } + if v == prev { + break DALOOP } } + fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) os.Exit(0) } diff --git a/benches/bench_jobs/main.go b/benches/bench_jobs/main.go index 3ba5f165..7676348c 100644 --- a/benches/bench_jobs/main.go +++ b/benches/bench_jobs/main.go @@ -82,22 +82,19 @@ func monitor() { prev := int64(0) DALOOP: - for { - select { - case <-t: - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v + for range t { + curT++ + v := atomic.AddInt64(&totcount, 0) + fmt.Printf("after %d seconds, count is %d\n", curT, v) + if curT == 1 { + c1 = v + } else if curT == 3 { + c2 = v + } + if v == prev { + break DALOOP } + prev = v } fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) os.Exit(0) diff --git a/benches/bench_work/main.go b/benches/bench_work/main.go index aaf1de69..0b0593b7 100644 --- a/benches/bench_work/main.go +++ b/benches/bench_work/main.go @@ -63,23 +63,21 @@ func monitor() { prev := int64(0) DALOOP: - for { - select { - case <-t: - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v + for range t { + curT++ + v := atomic.AddInt64(&totcount, 0) + fmt.Printf("after %d seconds, count is %d\n", curT, v) + if curT == 1 { + c1 = v + } else if curT == 3 { + c2 = v } + if v == prev { + break DALOOP + } + prev = v } + fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) os.Exit(0) } diff --git a/client_test.go b/client_test.go index dc012441..c43e3265 100644 --- a/client_test.go +++ b/client_test.go @@ -12,8 +12,8 @@ import ( type TestContext struct{} func TestClientWorkerPoolHeartbeats(t *testing.T) { - pool := newTestPool(":6379") - ns := "work" + pool := newTestPool() + ns := "TestClientWorkerPoolHeartbeats" cleanKeyspace(ns, pool) wp := NewWorkerPool(TestContext{}, 10, ns, pool) @@ -64,8 +64,8 @@ func TestClientWorkerPoolHeartbeats(t *testing.T) { } func TestClientWorkerObservations(t *testing.T) { - pool := newTestPool(":6379") - ns := "work" + pool := newTestPool() + ns := "TestClientWorkerObservations" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -133,14 +133,17 @@ func TestClientWorkerObservations(t *testing.T) { } func TestClientQueues(t *testing.T) { - pool := newTestPool(":6379") - ns := "work" + pool := newTestPool() + ns := "TestClientQueues" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) _, err := enqueuer.Enqueue("wat", nil) + assert.NoError(t, err) _, err = enqueuer.Enqueue("foo", nil) + assert.NoError(t, err) _, err = enqueuer.Enqueue("zaz", nil) + assert.NoError(t, err) // Start a pool to work on it. It's going to work on the queues // side effect of that is knowing which jobs are avail @@ -184,8 +187,8 @@ func TestClientQueues(t *testing.T) { } func TestClientScheduledJobs(t *testing.T) { - pool := newTestPool(":6379") - ns := "work" + pool := newTestPool() + ns := "TestClientScheduledJobs" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -193,8 +196,11 @@ func TestClientScheduledJobs(t *testing.T) { setNowEpochSecondsMock(1425263409) defer resetNowEpochSecondsMock() _, err := enqueuer.EnqueueIn("wat", 0, Q{"a": 1, "b": 2}) + assert.NoError(t, err) _, err = enqueuer.EnqueueIn("zaz", 4, Q{"a": 3, "b": 4}) + assert.NoError(t, err) _, err = enqueuer.EnqueueIn("foo", 2, Q{"a": 3, "b": 4}) + assert.NoError(t, err) client := NewClient(ns, pool) jobs, count, err := client.ScheduledJobs(1) @@ -232,8 +238,8 @@ func TestClientScheduledJobs(t *testing.T) { } func TestClientRetryJobs(t *testing.T) { - pool := newTestPool(":6379") - ns := "work" + pool := newTestPool() + ns := "TestClientRetryJobs" cleanKeyspace(ns, pool) setNowEpochSecondsMock(1425263409) @@ -271,8 +277,8 @@ func TestClientRetryJobs(t *testing.T) { } func TestClientDeadJobs(t *testing.T) { - pool := newTestPool(":6379") - ns := "testwork" + pool := newTestPool() + ns := "TestClientDeadJobs" cleanKeyspace(ns, pool) setNowEpochSecondsMock(1425263409) @@ -326,8 +332,8 @@ func TestClientDeadJobs(t *testing.T) { } func TestClientDeleteDeadJob(t *testing.T) { - pool := newTestPool(":6379") - ns := "testwork" + pool := newTestPool() + ns := "TestClientDeleteDeadJob" cleanKeyspace(ns, pool) // Insert a dead job: @@ -355,8 +361,8 @@ func TestClientDeleteDeadJob(t *testing.T) { } func TestClientRetryDeadJob(t *testing.T) { - pool := newTestPool(":6379") - ns := "testwork" + pool := newTestPool() + ns := "TestClientRetryDeadJob" cleanKeyspace(ns, pool) // Insert a dead job: @@ -411,7 +417,7 @@ func TestClientRetryDeadJob(t *testing.T) { } func TestClientRetryDeadJobWithArgs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -455,15 +461,15 @@ func TestClientRetryDeadJobWithArgs(t *testing.T) { } func TestClientDeleteAllDeadJobs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) // Insert a dead job: - insertDeadJob(ns, pool, "wat", 12345, 12347) - insertDeadJob(ns, pool, "wat", 12345, 12347) - insertDeadJob(ns, pool, "wat", 12345, 12349) - insertDeadJob(ns, pool, "wat", 12345, 12350) + insertDeadJob(ns, pool, "wat", 12344, 12347) + insertDeadJob(ns, pool, "wat", 12344, 12347) + insertDeadJob(ns, pool, "wat", 12344, 12349) + insertDeadJob(ns, pool, "wat", 12344, 12350) client := NewClient(ns, pool) jobs, count, err := client.DeadJobs(1) @@ -481,7 +487,7 @@ func TestClientDeleteAllDeadJobs(t *testing.T) { } func TestClientRetryAllDeadJobs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -539,7 +545,7 @@ func TestClientRetryAllDeadJobs(t *testing.T) { } func TestClientRetryAllDeadJobsBig(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -608,7 +614,7 @@ func TestClientRetryAllDeadJobsBig(t *testing.T) { } func TestClientDeleteScheduledJob(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -629,7 +635,7 @@ func TestClientDeleteScheduledJob(t *testing.T) { } func TestClientDeleteScheduledUniqueJob(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -650,7 +656,7 @@ func TestClientDeleteScheduledUniqueJob(t *testing.T) { } func TestClientDeleteRetryJob(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -683,7 +689,7 @@ func TestClientDeleteRetryJob(t *testing.T) { } } -func insertDeadJob(ns string, pool *redis.Pool, name string, encAt, failAt int64) *Job { +func insertDeadJob(ns string, pool *redis.Pool, name string, encAt, failAt int64) { job := &Job{ Name: name, ID: makeIdentifier(), @@ -707,7 +713,6 @@ func insertDeadJob(ns string, pool *redis.Pool, name string, encAt, failAt int64 panic(err) } - return job } func getQueuedJob(ns string, pool *redis.Pool, name string) *Job { diff --git a/cmd/workfakedata/main.go b/cmd/workfakedata/main.go index 72e77b04..2347cec0 100644 --- a/cmd/workfakedata/main.go +++ b/cmd/workfakedata/main.go @@ -1,9 +1,10 @@ package main import ( + "crypto/rand" "flag" "fmt" - "math/rand" + "math/big" "time" "github.com/gocraft/work" @@ -17,7 +18,12 @@ func epsilonHandler(job *work.Job) error { fmt.Println("epsilon") time.Sleep(time.Second) - if rand.Intn(2) == 0 { + n, err := rand.Int(rand.Reader, big.NewInt(2)) + if err != nil { + panic(err) + } + + if n.Int64() == 0 { return fmt.Errorf("random error") } return nil diff --git a/cmd/workwebui/main.go b/cmd/workwebui/main.go index 6d3e32fc..5bd41b5c 100644 --- a/cmd/workwebui/main.go +++ b/cmd/workwebui/main.go @@ -6,6 +6,7 @@ import ( "os" "os/signal" "strconv" + "syscall" "time" "github.com/gocraft/work/webui" @@ -40,7 +41,7 @@ func main() { server.Start() c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, os.Kill) + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) <-c diff --git a/dead_pool_reaper.go b/dead_pool_reaper.go index e930521e..f9149db3 100644 --- a/dead_pool_reaper.go +++ b/dead_pool_reaper.go @@ -1,8 +1,9 @@ package work import ( + "crypto/rand" "fmt" - "math/rand" + "math/big" "strings" "time" @@ -59,8 +60,13 @@ func (r *deadPoolReaper) loop() { r.doneStoppingChan <- struct{}{} return case <-timer.C: + n, err := rand.Int(rand.Reader, big.NewInt(reapJitterSecs)) + if err != nil { + panic(err) + } + // Schedule next occurrence periodically with jitter - timer.Reset(r.reapPeriod + time.Duration(rand.Intn(reapJitterSecs))*time.Second) + timer.Reset(r.reapPeriod + time.Duration(n.Int64())*time.Second) // Reap if err := r.reap(); err != nil { diff --git a/dead_pool_reaper_test.go b/dead_pool_reaper_test.go index 6c21cbc6..20392709 100644 --- a/dead_pool_reaper_test.go +++ b/dead_pool_reaper_test.go @@ -9,7 +9,7 @@ import ( ) func TestDeadPoolReaper(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -92,7 +92,7 @@ func TestDeadPoolReaper(t *testing.T) { } func TestDeadPoolReaperNoHeartbeat(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" conn := pool.Get() @@ -179,7 +179,7 @@ func TestDeadPoolReaperNoHeartbeat(t *testing.T) { } func TestDeadPoolReaperNoJobTypes(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -255,7 +255,7 @@ func TestDeadPoolReaperNoJobTypes(t *testing.T) { } func TestDeadPoolReaperWithWorkerPools(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" stalePoolID := "aaa" @@ -295,7 +295,7 @@ func TestDeadPoolReaperWithWorkerPools(t *testing.T) { } func TestDeadPoolReaperCleanStaleLocks(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -341,7 +341,9 @@ func TestDeadPoolReaperCleanStaleLocks(t *testing.T) { assert.EqualValues(t, 0, getInt64(pool, lock2)) // worker pool ID 2 removed from both lock info hashes v, err = conn.Do("HGET", lockInfo1, workerPoolID2) + assert.NoError(t, err) assert.Nil(t, v) v, err = conn.Do("HGET", lockInfo2, workerPoolID2) assert.Nil(t, v) + assert.NoError(t, err) } diff --git a/enqueue_test.go b/enqueue_test.go index 8ca41fa6..046455f9 100644 --- a/enqueue_test.go +++ b/enqueue_test.go @@ -10,7 +10,7 @@ import ( ) func TestEnqueue(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -46,13 +46,14 @@ func TestEnqueue(t *testing.T) { // Now enqueue another job, make sure that we can enqueue multiple _, err = enqueuer.Enqueue("wat", Q{"a": 1, "b": "cool"}) + assert.NoError(t, err) _, err = enqueuer.Enqueue("wat", Q{"a": 1, "b": "cool"}) - assert.Nil(t, err) + assert.NoError(t, err) assert.EqualValues(t, 2, listSize(pool, redisKeyJobs(ns, "wat"))) } func TestEnqueueIn(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -99,7 +100,7 @@ func TestEnqueueIn(t *testing.T) { } func TestEnqueueUnique(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -175,7 +176,7 @@ func TestEnqueueUnique(t *testing.T) { } func TestEnqueueUniqueIn(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -235,7 +236,7 @@ func TestEnqueueUniqueByKey(t *testing.T) { var arg3 string var arg4 string - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -314,43 +315,3 @@ func TestEnqueueUniqueByKey(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, job) } - -func EnqueueUniqueInByKey(t *testing.T) { - pool := newTestPool(":6379") - ns := "work" - cleanKeyspace(ns, pool) - enqueuer := NewEnqueuer(ns, pool) - - // Enqueue two unique jobs -- ensure one job sticks. - job, err := enqueuer.EnqueueUniqueInByKey("wat", 300, Q{"a": 1, "b": "cool"}, Q{"key": "123"}) - assert.NoError(t, err) - if assert.NotNil(t, job) { - assert.Equal(t, "wat", job.Name) - assert.True(t, len(job.ID) > 10) // Something is in it - assert.True(t, job.EnqueuedAt > (time.Now().Unix()-10)) // Within 10 seconds - assert.True(t, job.EnqueuedAt < (time.Now().Unix()+10)) // Within 10 seconds - assert.Equal(t, "cool", job.ArgString("b")) - assert.EqualValues(t, 1, job.ArgInt64("a")) - assert.NoError(t, job.ArgError()) - assert.EqualValues(t, job.EnqueuedAt+300, job.RunAt) - } - - job, err = enqueuer.EnqueueUniqueInByKey("wat", 10, Q{"a": 1, "b": "cool"}, Q{"key": "123"}) - assert.NoError(t, err) - assert.Nil(t, job) - - // Get the job - score, j := jobOnZset(pool, redisKeyScheduled(ns)) - - assert.True(t, score > time.Now().Unix()+290) // We don't want to overwrite the time - assert.True(t, score <= time.Now().Unix()+300) - - assert.Equal(t, "wat", j.Name) - assert.True(t, len(j.ID) > 10) // Something is in it - assert.True(t, j.EnqueuedAt > (time.Now().Unix()-10)) // Within 10 seconds - assert.True(t, j.EnqueuedAt < (time.Now().Unix()+10)) // Within 10 seconds - assert.Equal(t, "cool", j.ArgString("b")) - assert.EqualValues(t, 1, j.ArgInt64("a")) - assert.NoError(t, j.ArgError()) - assert.True(t, j.Unique) -} diff --git a/etc/out/profile.cov b/etc/out/profile.cov new file mode 100644 index 00000000..6003da00 --- /dev/null +++ b/etc/out/profile.cov @@ -0,0 +1,731 @@ +mode: atomic +github.com/gocraft/work/webui/webui.go:33.77,44.105 3 9 +github.com/gocraft/work/webui/webui.go:48.2,48.93 1 9 +github.com/gocraft/work/webui/webui.go:52.2,67.81 12 9 +github.com/gocraft/work/webui/webui.go:71.2,71.88 1 9 +github.com/gocraft/work/webui/webui.go:76.2,76.15 1 9 +github.com/gocraft/work/webui/webui.go:44.105,47.3 2 20 +github.com/gocraft/work/webui/webui.go:48.93,51.3 2 20 +github.com/gocraft/work/webui/webui.go:67.81,70.3 2 1 +github.com/gocraft/work/webui/webui.go:71.88,74.3 2 1 +github.com/gocraft/work/webui/webui.go:80.26,82.21 2 1 +github.com/gocraft/work/webui/webui.go:82.21,85.3 2 1 +github.com/gocraft/work/webui/webui.go:89.25,92.2 2 1 +github.com/gocraft/work/webui/webui.go:94.65,97.2 2 3 +github.com/gocraft/work/webui/webui.go:99.70,102.2 2 1 +github.com/gocraft/work/webui/webui.go:104.70,106.16 2 2 +github.com/gocraft/work/webui/webui.go:111.2,112.34 2 2 +github.com/gocraft/work/webui/webui.go:118.2,118.35 1 2 +github.com/gocraft/work/webui/webui.go:106.16,109.3 2 0 +github.com/gocraft/work/webui/webui.go:112.34,113.16 1 42 +github.com/gocraft/work/webui/webui.go:113.16,115.4 1 1 +github.com/gocraft/work/webui/webui.go:121.68,123.16 2 1 +github.com/gocraft/work/webui/webui.go:128.2,129.16 2 1 +github.com/gocraft/work/webui/webui.go:134.2,139.27 2 1 +github.com/gocraft/work/webui/webui.go:123.16,126.3 2 0 +github.com/gocraft/work/webui/webui.go:129.16,132.3 2 0 +github.com/gocraft/work/webui/webui.go:142.72,144.16 2 1 +github.com/gocraft/work/webui/webui.go:149.2,150.16 2 1 +github.com/gocraft/work/webui/webui.go:155.2,160.27 2 1 +github.com/gocraft/work/webui/webui.go:144.16,147.3 2 0 +github.com/gocraft/work/webui/webui.go:150.16,153.3 2 0 +github.com/gocraft/work/webui/webui.go:163.67,165.16 2 6 +github.com/gocraft/work/webui/webui.go:170.2,171.16 2 6 +github.com/gocraft/work/webui/webui.go:176.2,181.27 2 6 +github.com/gocraft/work/webui/webui.go:165.16,168.3 2 0 +github.com/gocraft/work/webui/webui.go:171.16,174.3 2 0 +github.com/gocraft/work/webui/webui.go:184.72,186.16 2 1 +github.com/gocraft/work/webui/webui.go:191.2,193.52 2 1 +github.com/gocraft/work/webui/webui.go:186.16,189.3 2 0 +github.com/gocraft/work/webui/webui.go:196.71,198.16 2 1 +github.com/gocraft/work/webui/webui.go:203.2,205.52 2 1 +github.com/gocraft/work/webui/webui.go:198.16,201.3 2 0 +github.com/gocraft/work/webui/webui.go:208.76,211.2 2 1 +github.com/gocraft/work/webui/webui.go:213.75,216.2 2 1 +github.com/gocraft/work/webui/webui.go:218.69,219.16 1 18 +github.com/gocraft/work/webui/webui.go:224.2,225.16 2 18 +github.com/gocraft/work/webui/webui.go:229.2,229.20 1 18 +github.com/gocraft/work/webui/webui.go:219.16,222.3 2 0 +github.com/gocraft/work/webui/webui.go:225.16,228.3 2 0 +github.com/gocraft/work/webui/webui.go:232.53,235.2 2 0 +github.com/gocraft/work/webui/webui.go:237.46,239.16 2 8 +github.com/gocraft/work/webui/webui.go:243.2,244.19 2 8 +github.com/gocraft/work/webui/webui.go:248.2,249.24 2 8 +github.com/gocraft/work/webui/webui.go:239.16,241.3 1 0 +github.com/gocraft/work/webui/webui.go:244.19,246.3 1 8 +github.com/gocraft/work/worker_pool.go:44.46,45.23 1 4 +github.com/gocraft/work/worker_pool.go:48.2,48.22 1 1 +github.com/gocraft/work/worker_pool.go:45.23,47.3 1 3 +github.com/gocraft/work/worker_pool.go:88.103,90.2 1 16 +github.com/gocraft/work/worker_pool.go:94.148,95.17 1 16 +github.com/gocraft/work/worker_pool.go:99.2,111.44 4 16 +github.com/gocraft/work/worker_pool.go:116.2,116.11 1 16 +github.com/gocraft/work/worker_pool.go:95.17,96.53 1 0 +github.com/gocraft/work/worker_pool.go:111.44,114.3 2 120 +github.com/gocraft/work/worker_pool.go:122.62,130.62 4 1 +github.com/gocraft/work/worker_pool.go:135.2,137.31 2 0 +github.com/gocraft/work/worker_pool.go:141.2,141.11 1 0 +github.com/gocraft/work/worker_pool.go:130.62,133.3 2 0 +github.com/gocraft/work/worker_pool.go:137.31,139.3 1 0 +github.com/gocraft/work/worker_pool.go:148.68,150.2 1 13 +github.com/gocraft/work/worker_pool.go:154.99,164.41 5 21 +github.com/gocraft/work/worker_pool.go:169.2,171.31 2 20 +github.com/gocraft/work/worker_pool.go:175.2,175.11 1 20 +github.com/gocraft/work/worker_pool.go:164.41,167.3 2 16 +github.com/gocraft/work/worker_pool.go:171.31,173.3 1 147 +github.com/gocraft/work/worker_pool.go:182.84,186.16 3 0 +github.com/gocraft/work/worker_pool.go:190.2,192.11 2 0 +github.com/gocraft/work/worker_pool.go:186.16,187.13 1 0 +github.com/gocraft/work/worker_pool.go:196.31,197.16 1 16 +github.com/gocraft/work/worker_pool.go:200.2,206.31 4 15 +github.com/gocraft/work/worker_pool.go:210.2,214.29 5 15 +github.com/gocraft/work/worker_pool.go:197.16,199.3 1 1 +github.com/gocraft/work/worker_pool.go:206.31,208.3 1 119 +github.com/gocraft/work/worker_pool.go:218.30,219.17 1 16 +github.com/gocraft/work/worker_pool.go:222.2,225.31 3 15 +github.com/gocraft/work/worker_pool.go:232.2,237.28 6 15 +github.com/gocraft/work/worker_pool.go:219.17,221.3 1 1 +github.com/gocraft/work/worker_pool.go:225.31,227.22 2 119 +github.com/gocraft/work/worker_pool.go:227.22,230.4 2 119 +github.com/gocraft/work/worker_pool.go:241.31,243.31 2 7 +github.com/gocraft/work/worker_pool.go:250.2,250.11 1 7 +github.com/gocraft/work/worker_pool.go:243.31,245.22 2 46 +github.com/gocraft/work/worker_pool.go:245.22,248.4 2 46 +github.com/gocraft/work/worker_pool.go:253.40,255.29 2 15 +github.com/gocraft/work/worker_pool.go:258.2,263.27 6 15 +github.com/gocraft/work/worker_pool.go:255.29,257.3 1 19 +github.com/gocraft/work/worker_pool.go:266.44,268.31 2 17 +github.com/gocraft/work/worker_pool.go:271.2,272.13 2 17 +github.com/gocraft/work/worker_pool.go:268.31,270.3 1 140 +github.com/gocraft/work/worker_pool.go:275.47,276.27 1 15 +github.com/gocraft/work/worker_pool.go:280.2,285.29 6 12 +github.com/gocraft/work/worker_pool.go:289.2,289.56 1 12 +github.com/gocraft/work/worker_pool.go:276.27,278.3 1 3 +github.com/gocraft/work/worker_pool.go:285.29,287.3 1 19 +github.com/gocraft/work/worker_pool.go:289.56,291.3 1 0 +github.com/gocraft/work/worker_pool.go:294.57,295.27 1 15 +github.com/gocraft/work/worker_pool.go:299.2,301.44 3 12 +github.com/gocraft/work/worker_pool.go:295.27,297.3 1 3 +github.com/gocraft/work/worker_pool.go:301.44,302.115 1 19 +github.com/gocraft/work/worker_pool.go:302.115,304.4 1 0 +github.com/gocraft/work/worker_pool.go:309.48,310.38 1 16 +github.com/gocraft/work/worker_pool.go:310.38,311.51 1 0 +github.com/gocraft/work/worker_pool.go:315.67,316.39 1 21 +github.com/gocraft/work/worker_pool.go:316.39,317.83 1 1 +github.com/gocraft/work/worker_pool.go:321.70,322.42 1 1 +github.com/gocraft/work/worker_pool.go:322.42,323.112 1 1 +github.com/gocraft/work/worker_pool.go:335.122,339.24 3 2 +github.com/gocraft/work/worker_pool.go:345.2,361.12 16 2 +github.com/gocraft/work/worker_pool.go:339.24,341.3 1 0 +github.com/gocraft/work/worker_pool.go:341.8,343.3 1 2 +github.com/gocraft/work/worker_pool.go:364.71,367.35 2 30 +github.com/gocraft/work/worker_pool.go:371.2,374.17 3 30 +github.com/gocraft/work/worker_pool.go:378.2,381.41 3 27 +github.com/gocraft/work/worker_pool.go:385.2,386.16 2 26 +github.com/gocraft/work/worker_pool.go:401.2,401.13 1 22 +github.com/gocraft/work/worker_pool.go:367.35,369.3 1 0 +github.com/gocraft/work/worker_pool.go:374.17,376.3 1 3 +github.com/gocraft/work/worker_pool.go:381.41,383.3 1 1 +github.com/gocraft/work/worker_pool.go:386.16,387.40 1 18 +github.com/gocraft/work/worker_pool.go:387.40,389.4 1 1 +github.com/gocraft/work/worker_pool.go:390.8,390.23 1 8 +github.com/gocraft/work/worker_pool.go:390.23,391.45 1 6 +github.com/gocraft/work/worker_pool.go:394.3,394.40 1 5 +github.com/gocraft/work/worker_pool.go:391.45,393.4 1 1 +github.com/gocraft/work/worker_pool.go:394.40,396.4 1 0 +github.com/gocraft/work/worker_pool.go:397.8,399.3 1 2 +github.com/gocraft/work/worker_pool.go:404.74,407.35 2 12 +github.com/gocraft/work/worker_pool.go:411.2,414.17 3 12 +github.com/gocraft/work/worker_pool.go:418.2,421.41 3 9 +github.com/gocraft/work/worker_pool.go:425.2,427.16 3 8 +github.com/gocraft/work/worker_pool.go:448.2,448.13 1 2 +github.com/gocraft/work/worker_pool.go:407.35,409.3 1 0 +github.com/gocraft/work/worker_pool.go:414.17,416.3 1 3 +github.com/gocraft/work/worker_pool.go:421.41,423.3 1 1 +github.com/gocraft/work/worker_pool.go:427.16,428.40 1 3 +github.com/gocraft/work/worker_pool.go:431.3,431.42 1 1 +github.com/gocraft/work/worker_pool.go:428.40,430.4 1 2 +github.com/gocraft/work/worker_pool.go:431.42,433.4 1 0 +github.com/gocraft/work/worker_pool.go:434.8,434.23 1 5 +github.com/gocraft/work/worker_pool.go:434.23,435.45 1 3 +github.com/gocraft/work/worker_pool.go:438.3,438.40 1 2 +github.com/gocraft/work/worker_pool.go:441.3,441.42 1 2 +github.com/gocraft/work/worker_pool.go:435.45,437.4 1 1 +github.com/gocraft/work/worker_pool.go:438.40,440.4 1 0 +github.com/gocraft/work/worker_pool.go:441.42,443.4 1 1 +github.com/gocraft/work/worker_pool.go:444.8,446.3 1 2 +github.com/gocraft/work/worker_pool.go:451.62,452.27 1 21 +github.com/gocraft/work/worker_pool.go:456.2,456.27 1 21 +github.com/gocraft/work/worker_pool.go:460.2,460.31 1 21 +github.com/gocraft/work/worker_pool.go:464.2,464.16 1 21 +github.com/gocraft/work/worker_pool.go:452.27,454.3 1 13 +github.com/gocraft/work/worker_pool.go:456.27,458.3 1 16 +github.com/gocraft/work/worker_pool.go:460.31,461.66 1 0 +github.com/gocraft/work/periodic_enqueuer.go:32.109,40.2 1 17 +github.com/gocraft/work/periodic_enqueuer.go:42.37,44.2 1 16 +github.com/gocraft/work/periodic_enqueuer.go:46.36,49.2 2 16 +github.com/gocraft/work/periodic_enqueuer.go:51.36,54.16 2 16 +github.com/gocraft/work/periodic_enqueuer.go:57.2,60.24 3 16 +github.com/gocraft/work/periodic_enqueuer.go:67.2,67.6 1 16 +github.com/gocraft/work/periodic_enqueuer.go:54.16,55.13 1 0 +github.com/gocraft/work/periodic_enqueuer.go:60.24,62.17 2 12 +github.com/gocraft/work/periodic_enqueuer.go:62.17,64.4 1 1 +github.com/gocraft/work/periodic_enqueuer.go:67.6,68.10 1 16 +github.com/gocraft/work/periodic_enqueuer.go:69.22,71.10 2 16 +github.com/gocraft/work/periodic_enqueuer.go:72.18,74.18 2 0 +github.com/gocraft/work/periodic_enqueuer.go:78.4,79.26 2 0 +github.com/gocraft/work/periodic_enqueuer.go:74.18,75.15 1 0 +github.com/gocraft/work/periodic_enqueuer.go:79.26,81.19 2 0 +github.com/gocraft/work/periodic_enqueuer.go:81.19,83.6 1 0 +github.com/gocraft/work/periodic_enqueuer.go:89.45,97.37 6 14 +github.com/gocraft/work/periodic_enqueuer.go:123.2,125.12 2 14 +github.com/gocraft/work/periodic_enqueuer.go:97.37,98.82 1 6 +github.com/gocraft/work/periodic_enqueuer.go:98.82,112.18 5 40 +github.com/gocraft/work/periodic_enqueuer.go:116.4,117.18 2 40 +github.com/gocraft/work/periodic_enqueuer.go:112.18,114.5 1 0 +github.com/gocraft/work/periodic_enqueuer.go:117.18,119.5 1 0 +github.com/gocraft/work/periodic_enqueuer.go:128.50,133.25 4 18 +github.com/gocraft/work/periodic_enqueuer.go:140.2,140.85 1 7 +github.com/gocraft/work/periodic_enqueuer.go:133.25,135.3 1 10 +github.com/gocraft/work/periodic_enqueuer.go:135.8,135.23 1 8 +github.com/gocraft/work/periodic_enqueuer.go:135.23,138.3 2 1 +github.com/gocraft/work/periodic_enqueuer.go:143.66,145.2 1 40 +github.com/gocraft/work/requeuer.go:24.102,28.35 4 32 +github.com/gocraft/work/requeuer.go:31.2,46.3 3 32 +github.com/gocraft/work/requeuer.go:28.35,30.3 1 42 +github.com/gocraft/work/requeuer.go:49.28,51.2 1 32 +github.com/gocraft/work/requeuer.go:53.27,56.2 2 32 +github.com/gocraft/work/requeuer.go:58.28,61.2 2 2 +github.com/gocraft/work/requeuer.go:63.27,70.6 2 32 +github.com/gocraft/work/requeuer.go:70.6,71.10 1 48 +github.com/gocraft/work/requeuer.go:72.21,74.10 2 32 +github.com/gocraft/work/requeuer.go:75.22,76.20 1 2 +github.com/gocraft/work/requeuer.go:78.4,78.36 1 2 +github.com/gocraft/work/requeuer.go:79.17,80.20 1 14 +github.com/gocraft/work/requeuer.go:76.21,77.5 0 4 +github.com/gocraft/work/requeuer.go:80.21,81.5 0 0 +github.com/gocraft/work/requeuer.go:86.35,93.25 5 20 +github.com/gocraft/work/requeuer.go:100.2,100.15 1 4 +github.com/gocraft/work/requeuer.go:109.2,109.14 1 0 +github.com/gocraft/work/requeuer.go:93.25,95.3 1 12 +github.com/gocraft/work/requeuer.go:95.8,95.23 1 8 +github.com/gocraft/work/requeuer.go:95.23,98.3 2 4 +github.com/gocraft/work/requeuer.go:100.15,102.3 1 0 +github.com/gocraft/work/requeuer.go:102.8,102.26 1 4 +github.com/gocraft/work/requeuer.go:102.26,105.3 2 1 +github.com/gocraft/work/requeuer.go:105.8,105.24 1 3 +github.com/gocraft/work/requeuer.go:105.24,107.3 1 3 +github.com/gocraft/work/time.go:7.30,8.18 1 292 +github.com/gocraft/work/time.go:11.2,11.26 1 232 +github.com/gocraft/work/time.go:8.18,10.3 1 60 +github.com/gocraft/work/time.go:14.38,16.2 1 25 +github.com/gocraft/work/time.go:18.33,20.2 1 15 +github.com/gocraft/work/redis.go:9.52,11.40 2 2543 +github.com/gocraft/work/redis.go:14.2,14.18 1 2543 +github.com/gocraft/work/redis.go:11.40,13.3 1 2543 +github.com/gocraft/work/redis.go:17.49,19.2 1 77 +github.com/gocraft/work/redis.go:23.50,25.2 1 1818 +github.com/gocraft/work/redis.go:27.53,29.2 1 1746 +github.com/gocraft/work/redis.go:31.71,33.2 1 273 +github.com/gocraft/work/redis.go:35.45,37.2 1 37 +github.com/gocraft/work/redis.go:39.44,41.2 1 101 +github.com/gocraft/work/redis.go:43.49,45.2 1 89 +github.com/gocraft/work/redis.go:47.67,49.2 1 239 +github.com/gocraft/work/redis.go:51.51,53.2 1 58 +github.com/gocraft/work/redis.go:55.63,57.2 1 65 +github.com/gocraft/work/redis.go:59.59,61.2 1 234 +github.com/gocraft/work/redis.go:63.57,65.2 1 312 +github.com/gocraft/work/redis.go:67.61,69.2 1 316 +github.com/gocraft/work/redis.go:71.64,73.2 1 242 +github.com/gocraft/work/redis.go:75.96,83.17 6 25 +github.com/gocraft/work/redis.go:90.2,90.26 1 25 +github.com/gocraft/work/redis.go:83.17,85.17 2 15 +github.com/gocraft/work/redis.go:85.17,87.4 1 0 +github.com/gocraft/work/redis.go:93.59,95.2 1 34 +github.com/gocraft/work/dead_pool_reaper.go:31.98,41.2 1 20 +github.com/gocraft/work/dead_pool_reaper.go:43.34,45.2 1 16 +github.com/gocraft/work/dead_pool_reaper.go:47.33,50.2 2 16 +github.com/gocraft/work/dead_pool_reaper.go:52.33,57.6 3 16 +github.com/gocraft/work/dead_pool_reaper.go:57.6,58.10 1 17 +github.com/gocraft/work/dead_pool_reaper.go:59.21,61.10 2 16 +github.com/gocraft/work/dead_pool_reaper.go:62.18,64.18 2 1 +github.com/gocraft/work/dead_pool_reaper.go:69.4,72.35 2 1 +github.com/gocraft/work/dead_pool_reaper.go:64.18,65.15 1 0 +github.com/gocraft/work/dead_pool_reaper.go:72.35,74.5 1 0 +github.com/gocraft/work/dead_pool_reaper.go:79.39,82.16 2 4 +github.com/gocraft/work/dead_pool_reaper.go:86.2,92.48 4 4 +github.com/gocraft/work/dead_pool_reaper.go:114.2,114.12 1 4 +github.com/gocraft/work/dead_pool_reaper.go:82.16,84.3 1 0 +github.com/gocraft/work/dead_pool_reaper.go:92.48,95.24 2 7 +github.com/gocraft/work/dead_pool_reaper.go:105.3,105.71 1 7 +github.com/gocraft/work/dead_pool_reaper.go:109.3,109.71 1 7 +github.com/gocraft/work/dead_pool_reaper.go:95.24,97.87 2 4 +github.com/gocraft/work/dead_pool_reaper.go:97.87,99.5 1 0 +github.com/gocraft/work/dead_pool_reaper.go:100.9,103.4 1 3 +github.com/gocraft/work/dead_pool_reaper.go:105.71,107.4 1 0 +github.com/gocraft/work/dead_pool_reaper.go:109.71,111.4 1 0 +github.com/gocraft/work/dead_pool_reaper.go:117.85,122.35 4 9 +github.com/gocraft/work/dead_pool_reaper.go:125.2,129.72 4 9 +github.com/gocraft/work/dead_pool_reaper.go:133.2,133.12 1 9 +github.com/gocraft/work/dead_pool_reaper.go:122.35,124.3 1 14 +github.com/gocraft/work/dead_pool_reaper.go:129.72,131.3 1 0 +github.com/gocraft/work/dead_pool_reaper.go:136.88,141.35 4 4 +github.com/gocraft/work/dead_pool_reaper.go:145.2,151.6 4 4 +github.com/gocraft/work/dead_pool_reaper.go:141.35,144.3 1 7 +github.com/gocraft/work/dead_pool_reaper.go:151.6,153.26 2 7 +github.com/gocraft/work/dead_pool_reaper.go:159.3,159.23 1 3 +github.com/gocraft/work/dead_pool_reaper.go:153.26,155.4 1 4 +github.com/gocraft/work/dead_pool_reaper.go:155.9,155.24 1 3 +github.com/gocraft/work/dead_pool_reaper.go:155.24,157.4 1 0 +github.com/gocraft/work/dead_pool_reaper.go:159.23,161.4 1 0 +github.com/gocraft/work/dead_pool_reaper.go:165.71,172.16 5 7 +github.com/gocraft/work/dead_pool_reaper.go:176.2,177.45 2 7 +github.com/gocraft/work/dead_pool_reaper.go:205.2,205.23 1 7 +github.com/gocraft/work/dead_pool_reaper.go:172.16,174.3 1 0 +github.com/gocraft/work/dead_pool_reaper.go:177.45,180.26 3 17 +github.com/gocraft/work/dead_pool_reaper.go:185.3,185.17 1 11 +github.com/gocraft/work/dead_pool_reaper.go:190.3,190.66 1 11 +github.com/gocraft/work/dead_pool_reaper.go:194.3,195.26 2 9 +github.com/gocraft/work/dead_pool_reaper.go:198.3,198.17 1 7 +github.com/gocraft/work/dead_pool_reaper.go:202.3,202.61 1 7 +github.com/gocraft/work/dead_pool_reaper.go:180.26,183.12 2 6 +github.com/gocraft/work/dead_pool_reaper.go:185.17,187.4 1 0 +github.com/gocraft/work/dead_pool_reaper.go:190.66,191.12 1 2 +github.com/gocraft/work/dead_pool_reaper.go:195.26,196.12 1 2 +github.com/gocraft/work/dead_pool_reaper.go:198.17,200.4 1 0 +github.com/gocraft/work/job.go:36.70,39.16 3 171 +github.com/gocraft/work/job.go:42.2,45.18 4 171 +github.com/gocraft/work/job.go:39.16,41.3 1 0 +github.com/gocraft/work/job.go:48.43,50.2 1 10166 +github.com/gocraft/work/job.go:53.51,54.19 1 36 +github.com/gocraft/work/job.go:57.2,57.19 1 36 +github.com/gocraft/work/job.go:54.19,56.3 1 5 +github.com/gocraft/work/job.go:60.33,64.2 3 9 +github.com/gocraft/work/job.go:67.35,68.23 1 1 +github.com/gocraft/work/job.go:68.23,70.3 1 1 +github.com/gocraft/work/job.go:76.44,78.8 2 16 +github.com/gocraft/work/job.go:87.2,87.11 1 4 +github.com/gocraft/work/job.go:78.8,80.9 2 14 +github.com/gocraft/work/job.go:83.3,83.47 1 2 +github.com/gocraft/work/job.go:80.9,82.4 1 12 +github.com/gocraft/work/job.go:84.8,86.3 1 2 +github.com/gocraft/work/job.go:93.42,95.8 2 37 +github.com/gocraft/work/job.go:115.2,115.10 1 7 +github.com/gocraft/work/job.go:95.8,97.22 2 36 +github.com/gocraft/work/job.go:111.3,111.46 1 6 +github.com/gocraft/work/job.go:97.22,99.4 1 12 +github.com/gocraft/work/job.go:99.9,99.30 1 24 +github.com/gocraft/work/job.go:99.30,101.30 2 3 +github.com/gocraft/work/job.go:101.30,103.5 1 2 +github.com/gocraft/work/job.go:104.9,104.31 1 21 +github.com/gocraft/work/job.go:104.31,107.101 3 19 +github.com/gocraft/work/job.go:107.101,109.5 1 16 +github.com/gocraft/work/job.go:112.8,114.3 1 1 +github.com/gocraft/work/job.go:121.46,123.8 2 12 +github.com/gocraft/work/job.go:136.2,136.12 1 3 +github.com/gocraft/work/job.go:123.8,125.22 2 11 +github.com/gocraft/work/job.go:132.3,132.48 1 2 +github.com/gocraft/work/job.go:125.22,127.4 1 4 +github.com/gocraft/work/job.go:127.9,127.30 1 7 +github.com/gocraft/work/job.go:127.30,129.4 1 0 +github.com/gocraft/work/job.go:129.9,129.31 1 7 +github.com/gocraft/work/job.go:129.31,131.4 1 5 +github.com/gocraft/work/job.go:133.8,135.3 1 1 +github.com/gocraft/work/job.go:142.40,144.8 2 7 +github.com/gocraft/work/job.go:153.2,153.14 1 3 +github.com/gocraft/work/job.go:144.8,146.9 2 6 +github.com/gocraft/work/job.go:149.3,149.45 1 2 +github.com/gocraft/work/job.go:146.9,148.4 1 4 +github.com/gocraft/work/job.go:150.8,152.3 1 1 +github.com/gocraft/work/job.go:157.32,159.2 1 54 +github.com/gocraft/work/job.go:161.38,164.2 2 47 +github.com/gocraft/work/job.go:166.39,169.2 2 31 +github.com/gocraft/work/job.go:171.40,174.2 2 28 +github.com/gocraft/work/job.go:176.50,178.2 1 5 +github.com/gocraft/work/job.go:180.63,183.2 2 12 +github.com/gocraft/work/priority_sampler.go:26.157,38.2 3 226 +github.com/gocraft/work/priority_sampler.go:47.49,59.20 5 471 +github.com/gocraft/work/priority_sampler.go:85.2,85.18 1 471 +github.com/gocraft/work/priority_sampler.go:59.20,61.17 2 532 +github.com/gocraft/work/priority_sampler.go:66.3,68.51 3 532 +github.com/gocraft/work/priority_sampler.go:81.3,82.14 2 532 +github.com/gocraft/work/priority_sampler.go:61.17,62.14 1 0 +github.com/gocraft/work/priority_sampler.go:68.51,70.40 2 1014 +github.com/gocraft/work/priority_sampler.go:70.40,75.10 3 532 +github.com/gocraft/work/priority_sampler.go:76.10,78.5 1 482 +github.com/gocraft/work/run.go:10.136,16.22 5 50 +github.com/gocraft/work/run.go:41.2,41.15 1 50 +github.com/gocraft/work/run.go:51.2,51.26 1 50 +github.com/gocraft/work/run.go:16.22,17.40 1 55 +github.com/gocraft/work/run.go:30.3,30.19 1 48 +github.com/gocraft/work/run.go:33.3,35.15 3 24 +github.com/gocraft/work/run.go:38.3,38.19 1 1 +github.com/gocraft/work/run.go:17.40,20.20 3 7 +github.com/gocraft/work/run.go:23.4,25.16 3 2 +github.com/gocraft/work/run.go:28.4,28.20 1 0 +github.com/gocraft/work/run.go:20.20,22.5 1 5 +github.com/gocraft/work/run.go:25.16,27.5 1 2 +github.com/gocraft/work/run.go:30.19,32.4 1 24 +github.com/gocraft/work/run.go:35.15,37.4 1 22 +github.com/gocraft/work/run.go:41.15,42.45 1 50 +github.com/gocraft/work/run.go:42.45,48.4 3 2 +github.com/gocraft/work/worker.go:36.154,40.29 3 126 +github.com/gocraft/work/worker.go:44.2,63.10 3 126 +github.com/gocraft/work/worker.go:40.29,42.3 1 126 +github.com/gocraft/work/worker.go:67.109,70.30 3 273 +github.com/gocraft/work/worker.go:79.2,81.91 3 273 +github.com/gocraft/work/worker.go:70.30,78.3 1 223 +github.com/gocraft/work/worker.go:84.26,87.2 2 125 +github.com/gocraft/work/worker.go:89.25,94.2 4 125 +github.com/gocraft/work/worker.go:96.26,100.2 3 52 +github.com/gocraft/work/worker.go:104.25,112.6 5 125 +github.com/gocraft/work/worker.go:112.6,113.10 1 448 +github.com/gocraft/work/worker.go:114.21,116.10 2 125 +github.com/gocraft/work/worker.go:117.22,119.18 2 52 +github.com/gocraft/work/worker.go:120.18,122.18 2 271 +github.com/gocraft/work/worker.go:122.18,125.5 2 10 +github.com/gocraft/work/worker.go:125.10,125.25 1 261 +github.com/gocraft/work/worker.go:125.25,129.5 3 45 +github.com/gocraft/work/worker.go:129.10,130.16 1 216 +github.com/gocraft/work/worker.go:134.5,136.43 3 216 +github.com/gocraft/work/worker.go:139.5,139.72 1 216 +github.com/gocraft/work/worker.go:130.16,133.6 2 52 +github.com/gocraft/work/worker.go:136.43,138.6 1 3 +github.com/gocraft/work/worker.go:145.43,152.38 4 271 +github.com/gocraft/work/worker.go:155.2,160.25 5 271 +github.com/gocraft/work/worker.go:166.2,166.22 1 45 +github.com/gocraft/work/worker.go:170.2,171.9 2 45 +github.com/gocraft/work/worker.go:175.2,176.9 2 45 +github.com/gocraft/work/worker.go:180.2,181.9 2 45 +github.com/gocraft/work/worker.go:185.2,186.16 2 45 +github.com/gocraft/work/worker.go:190.2,190.17 1 45 +github.com/gocraft/work/worker.go:152.38,154.3 1 373 +github.com/gocraft/work/worker.go:160.25,162.3 1 216 +github.com/gocraft/work/worker.go:162.8,162.23 1 55 +github.com/gocraft/work/worker.go:162.23,164.3 1 10 +github.com/gocraft/work/worker.go:166.22,168.3 1 0 +github.com/gocraft/work/worker.go:171.9,173.3 1 0 +github.com/gocraft/work/worker.go:176.9,178.3 1 0 +github.com/gocraft/work/worker.go:181.9,183.3 1 0 +github.com/gocraft/work/worker.go:186.16,188.3 1 0 +github.com/gocraft/work/worker.go:193.39,194.16 1 45 +github.com/gocraft/work/worker.go:203.2,205.15 3 45 +github.com/gocraft/work/worker.go:215.2,216.19 2 45 +github.com/gocraft/work/worker.go:220.2,220.38 1 45 +github.com/gocraft/work/worker.go:194.16,199.24 2 7 +github.com/gocraft/work/worker.go:199.24,201.4 1 3 +github.com/gocraft/work/worker.go:205.15,208.3 2 0 +github.com/gocraft/work/worker.go:208.8,213.3 4 45 +github.com/gocraft/work/worker.go:216.19,219.3 2 9 +github.com/gocraft/work/worker.go:223.55,227.25 3 7 +github.com/gocraft/work/worker.go:237.2,241.16 4 7 +github.com/gocraft/work/worker.go:246.2,247.16 2 7 +github.com/gocraft/work/worker.go:254.2,254.28 1 7 +github.com/gocraft/work/worker.go:259.2,260.16 2 3 +github.com/gocraft/work/worker.go:265.2,265.20 1 3 +github.com/gocraft/work/worker.go:227.25,229.3 1 7 +github.com/gocraft/work/worker.go:229.8,231.17 2 0 +github.com/gocraft/work/worker.go:231.17,234.4 2 0 +github.com/gocraft/work/worker.go:241.16,244.3 2 0 +github.com/gocraft/work/worker.go:247.16,250.3 2 0 +github.com/gocraft/work/worker.go:254.28,256.3 1 4 +github.com/gocraft/work/worker.go:260.16,263.3 2 0 +github.com/gocraft/work/worker.go:268.70,277.43 8 45 +github.com/gocraft/work/worker.go:277.43,279.3 1 0 +github.com/gocraft/work/worker.go:284.35,284.36 0 37 +github.com/gocraft/work/worker.go:285.70,287.16 2 4 +github.com/gocraft/work/worker.go:291.2,291.31 1 4 +github.com/gocraft/work/worker.go:287.16,290.3 2 0 +github.com/gocraft/work/worker.go:291.31,293.3 1 4 +github.com/gocraft/work/worker.go:295.56,297.16 2 4 +github.com/gocraft/work/worker.go:301.2,301.31 1 4 +github.com/gocraft/work/worker.go:297.16,300.3 2 0 +github.com/gocraft/work/worker.go:301.31,308.3 1 4 +github.com/gocraft/work/worker.go:311.61,312.15 1 9 +github.com/gocraft/work/worker.go:321.2,321.33 1 4 +github.com/gocraft/work/worker.go:312.15,314.25 2 9 +github.com/gocraft/work/worker.go:317.3,317.18 1 5 +github.com/gocraft/work/worker.go:314.25,316.4 1 4 +github.com/gocraft/work/worker.go:317.18,319.4 1 1 +github.com/gocraft/work/worker.go:325.47,328.16 3 3 +github.com/gocraft/work/worker.go:332.2,332.73 1 3 +github.com/gocraft/work/worker.go:328.16,329.13 1 0 +github.com/gocraft/work/heartbeater.go:32.179,44.26 3 17 +github.com/gocraft/work/heartbeater.go:47.2,55.16 7 17 +github.com/gocraft/work/heartbeater.go:59.2,61.10 2 17 +github.com/gocraft/work/heartbeater.go:44.26,46.3 1 22 +github.com/gocraft/work/heartbeater.go:55.16,58.3 2 0 +github.com/gocraft/work/heartbeater.go:64.41,66.2 1 17 +github.com/gocraft/work/heartbeater.go:68.40,71.2 2 17 +github.com/gocraft/work/heartbeater.go:73.40,77.6 4 17 +github.com/gocraft/work/heartbeater.go:77.6,78.10 1 18 +github.com/gocraft/work/heartbeater.go:79.21,82.10 3 17 +github.com/gocraft/work/heartbeater.go:83.17,84.17 1 1 +github.com/gocraft/work/heartbeater.go:89.45,107.37 7 18 +github.com/gocraft/work/heartbeater.go:107.37,109.3 1 1 +github.com/gocraft/work/heartbeater.go:112.51,122.37 7 17 +github.com/gocraft/work/heartbeater.go:122.37,124.3 1 1 +github.com/gocraft/work/identifier.go:9.30,12.16 3 10261 +github.com/gocraft/work/identifier.go:15.2,15.29 1 10261 +github.com/gocraft/work/identifier.go:12.16,14.3 1 0 +github.com/gocraft/work/observer.go:65.81,78.2 1 130 +github.com/gocraft/work/observer.go:80.28,82.2 1 129 +github.com/gocraft/work/observer.go:84.27,87.2 2 129 +github.com/gocraft/work/observer.go:89.28,92.2 2 183 +github.com/gocraft/work/observer.go:94.92,102.2 1 49 +github.com/gocraft/work/observer.go:104.66,111.2 1 46 +github.com/gocraft/work/observer.go:113.67,121.2 1 2 +github.com/gocraft/work/observer.go:123.27,129.6 2 129 +github.com/gocraft/work/observer.go:129.6,130.10 1 430 +github.com/gocraft/work/observer.go:131.21,133.10 2 129 +github.com/gocraft/work/observer.go:134.22,136.8 1 183 +github.com/gocraft/work/observer.go:148.17,149.41 1 27 +github.com/gocraft/work/observer.go:155.36,156.18 1 91 +github.com/gocraft/work/observer.go:136.8,137.12 1 189 +github.com/gocraft/work/observer.go:138.38,139.20 1 6 +github.com/gocraft/work/observer.go:140.13,141.71 1 183 +github.com/gocraft/work/observer.go:144.6,145.22 2 183 +github.com/gocraft/work/observer.go:141.71,143.7 1 10 +github.com/gocraft/work/observer.go:149.41,150.70 1 8 +github.com/gocraft/work/observer.go:153.5,153.37 1 8 +github.com/gocraft/work/observer.go:150.70,152.6 1 0 +github.com/gocraft/work/observer.go:161.46,162.40 1 97 +github.com/gocraft/work/observer.go:174.2,177.20 2 97 +github.com/gocraft/work/observer.go:162.40,164.3 1 49 +github.com/gocraft/work/observer.go:164.8,164.44 1 48 +github.com/gocraft/work/observer.go:164.44,166.3 1 46 +github.com/gocraft/work/observer.go:166.8,166.47 1 2 +github.com/gocraft/work/observer.go:166.47,167.95 1 2 +github.com/gocraft/work/observer.go:167.95,170.4 2 2 +github.com/gocraft/work/observer.go:170.9,172.4 1 0 +github.com/gocraft/work/observer.go:177.20,178.68 1 29 +github.com/gocraft/work/observer.go:181.3,181.35 1 29 +github.com/gocraft/work/observer.go:178.68,180.4 1 0 +github.com/gocraft/work/observer.go:185.56,191.16 4 220 +github.com/gocraft/work/observer.go:239.2,239.12 1 210 +github.com/gocraft/work/observer.go:191.16,192.48 1 178 +github.com/gocraft/work/observer.go:192.48,194.4 1 10 +github.com/gocraft/work/observer.go:195.8,205.30 2 42 +github.com/gocraft/work/observer.go:215.3,224.49 3 42 +github.com/gocraft/work/observer.go:231.3,233.38 3 42 +github.com/gocraft/work/observer.go:205.30,207.4 1 16 +github.com/gocraft/work/observer.go:207.9,210.18 3 26 +github.com/gocraft/work/observer.go:210.18,212.5 1 0 +github.com/gocraft/work/observer.go:224.49,229.4 1 2 +github.com/gocraft/work/observer.go:233.38,235.4 1 0 +github.com/gocraft/work/client.go:27.60,32.2 1 16 +github.com/gocraft/work/client.go:47.73,54.16 5 4 +github.com/gocraft/work/client.go:57.2,59.37 2 4 +github.com/gocraft/work/client.go:64.2,64.37 1 4 +github.com/gocraft/work/client.go:69.2,71.37 2 4 +github.com/gocraft/work/client.go:117.2,117.24 1 4 +github.com/gocraft/work/client.go:54.16,56.3 1 0 +github.com/gocraft/work/client.go:59.37,62.3 2 3 +github.com/gocraft/work/client.go:64.37,67.3 2 0 +github.com/gocraft/work/client.go:71.37,73.17 2 3 +github.com/gocraft/work/client.go:78.3,82.39 2 3 +github.com/gocraft/work/client.go:114.3,114.45 1 3 +github.com/gocraft/work/client.go:73.17,76.4 2 0 +github.com/gocraft/work/client.go:82.39,87.29 4 21 +github.com/gocraft/work/client.go:108.4,108.18 1 21 +github.com/gocraft/work/client.go:87.29,89.5 1 3 +github.com/gocraft/work/client.go:89.10,89.34 1 18 +github.com/gocraft/work/client.go:89.34,91.5 1 3 +github.com/gocraft/work/client.go:91.10,91.33 1 15 +github.com/gocraft/work/client.go:91.33,94.5 2 3 +github.com/gocraft/work/client.go:94.10,94.35 1 12 +github.com/gocraft/work/client.go:94.35,98.5 3 3 +github.com/gocraft/work/client.go:98.10,98.28 1 9 +github.com/gocraft/work/client.go:98.28,100.5 1 3 +github.com/gocraft/work/client.go:100.10,100.27 1 6 +github.com/gocraft/work/client.go:100.27,104.5 3 3 +github.com/gocraft/work/client.go:104.10,104.34 1 3 +github.com/gocraft/work/client.go:104.34,107.5 2 3 +github.com/gocraft/work/client.go:108.18,111.5 2 0 +github.com/gocraft/work/client.go:135.69,140.16 4 2 +github.com/gocraft/work/client.go:145.2,146.25 2 2 +github.com/gocraft/work/client.go:150.2,150.32 1 2 +github.com/gocraft/work/client.go:155.2,155.37 1 2 +github.com/gocraft/work/client.go:160.2,162.32 2 2 +github.com/gocraft/work/client.go:202.2,202.26 1 2 +github.com/gocraft/work/client.go:140.16,143.3 2 0 +github.com/gocraft/work/client.go:146.25,148.3 1 1 +github.com/gocraft/work/client.go:150.32,153.3 2 10 +github.com/gocraft/work/client.go:155.37,158.3 2 0 +github.com/gocraft/work/client.go:162.32,164.17 2 10 +github.com/gocraft/work/client.go:169.3,173.39 2 10 +github.com/gocraft/work/client.go:199.3,199.42 1 10 +github.com/gocraft/work/client.go:164.17,167.4 2 0 +github.com/gocraft/work/client.go:173.39,180.25 5 8 +github.com/gocraft/work/client.go:193.4,193.18 1 8 +github.com/gocraft/work/client.go:180.25,182.5 1 2 +github.com/gocraft/work/client.go:182.10,182.30 1 6 +github.com/gocraft/work/client.go:182.30,184.5 1 2 +github.com/gocraft/work/client.go:184.10,184.34 1 4 +github.com/gocraft/work/client.go:184.34,186.5 1 2 +github.com/gocraft/work/client.go:186.10,186.28 1 2 +github.com/gocraft/work/client.go:186.28,188.5 1 2 +github.com/gocraft/work/client.go:188.10,188.31 1 0 +github.com/gocraft/work/client.go:188.31,190.5 1 0 +github.com/gocraft/work/client.go:190.10,190.34 1 0 +github.com/gocraft/work/client.go:190.34,192.5 1 0 +github.com/gocraft/work/client.go:193.18,196.5 2 0 +github.com/gocraft/work/client.go:213.45,219.16 5 8 +github.com/gocraft/work/client.go:222.2,224.35 2 8 +github.com/gocraft/work/client.go:228.2,228.37 1 8 +github.com/gocraft/work/client.go:233.2,235.35 2 8 +github.com/gocraft/work/client.go:250.2,250.27 1 8 +github.com/gocraft/work/client.go:256.2,256.37 1 8 +github.com/gocraft/work/client.go:261.2,263.27 2 8 +github.com/gocraft/work/client.go:279.2,279.20 1 8 +github.com/gocraft/work/client.go:219.16,221.3 1 0 +github.com/gocraft/work/client.go:224.35,226.3 1 25 +github.com/gocraft/work/client.go:228.37,231.3 2 0 +github.com/gocraft/work/client.go:235.35,237.17 2 25 +github.com/gocraft/work/client.go:242.3,247.33 2 25 +github.com/gocraft/work/client.go:237.17,240.4 2 0 +github.com/gocraft/work/client.go:250.27,251.18 1 25 +github.com/gocraft/work/client.go:251.18,253.4 1 8 +github.com/gocraft/work/client.go:256.37,259.3 2 0 +github.com/gocraft/work/client.go:263.27,264.18 1 25 +github.com/gocraft/work/client.go:264.18,266.18 2 8 +github.com/gocraft/work/client.go:271.4,272.18 2 8 +github.com/gocraft/work/client.go:275.4,275.36 1 8 +github.com/gocraft/work/client.go:266.18,269.5 2 0 +github.com/gocraft/work/client.go:272.18,274.5 1 0 +github.com/gocraft/work/client.go:301.75,304.16 3 3 +github.com/gocraft/work/client.go:309.2,311.37 2 3 +github.com/gocraft/work/client.go:315.2,315.25 1 3 +github.com/gocraft/work/client.go:304.16,307.3 2 0 +github.com/gocraft/work/client.go:311.37,313.3 1 43 +github.com/gocraft/work/client.go:319.67,322.16 3 2 +github.com/gocraft/work/client.go:327.2,329.37 2 2 +github.com/gocraft/work/client.go:333.2,333.25 1 2 +github.com/gocraft/work/client.go:322.16,325.3 2 0 +github.com/gocraft/work/client.go:329.37,331.3 1 2 +github.com/gocraft/work/client.go:337.65,340.16 3 19 +github.com/gocraft/work/client.go:345.2,347.37 2 19 +github.com/gocraft/work/client.go:351.2,351.25 1 19 +github.com/gocraft/work/client.go:340.16,343.3 2 0 +github.com/gocraft/work/client.go:347.37,349.3 1 50 +github.com/gocraft/work/client.go:355.66,357.16 2 5 +github.com/gocraft/work/client.go:360.2,360.9 1 5 +github.com/gocraft/work/client.go:363.2,363.12 1 5 +github.com/gocraft/work/client.go:357.16,359.3 1 0 +github.com/gocraft/work/client.go:360.9,362.3 1 0 +github.com/gocraft/work/client.go:367.65,370.16 2 5 +github.com/gocraft/work/client.go:376.2,377.27 2 5 +github.com/gocraft/work/client.go:381.2,385.35 4 5 +github.com/gocraft/work/client.go:388.2,397.16 8 5 +github.com/gocraft/work/client.go:402.2,402.14 1 5 +github.com/gocraft/work/client.go:406.2,406.12 1 5 +github.com/gocraft/work/client.go:370.16,373.3 2 0 +github.com/gocraft/work/client.go:377.27,379.3 1 17 +github.com/gocraft/work/client.go:385.35,387.3 1 17 +github.com/gocraft/work/client.go:397.16,400.3 2 0 +github.com/gocraft/work/client.go:402.14,404.3 1 0 +github.com/gocraft/work/client.go:410.43,413.16 2 2 +github.com/gocraft/work/client.go:419.2,420.27 2 2 +github.com/gocraft/work/client.go:424.2,428.35 4 2 +github.com/gocraft/work/client.go:431.2,440.28 6 2 +github.com/gocraft/work/client.go:452.2,452.12 1 2 +github.com/gocraft/work/client.go:413.16,416.3 2 0 +github.com/gocraft/work/client.go:420.27,422.3 1 5 +github.com/gocraft/work/client.go:428.35,430.3 1 5 +github.com/gocraft/work/client.go:440.28,442.17 2 14 +github.com/gocraft/work/client.go:447.3,447.15 1 14 +github.com/gocraft/work/client.go:442.17,445.4 2 0 +github.com/gocraft/work/client.go:447.15,448.9 1 2 +github.com/gocraft/work/client.go:456.44,460.16 4 1 +github.com/gocraft/work/client.go:465.2,465.12 1 1 +github.com/gocraft/work/client.go:460.16,463.3 2 0 +github.com/gocraft/work/client.go:469.77,471.16 2 3 +github.com/gocraft/work/client.go:476.2,476.23 1 3 +github.com/gocraft/work/client.go:500.2,500.9 1 3 +github.com/gocraft/work/client.go:503.2,503.12 1 2 +github.com/gocraft/work/client.go:471.16,473.3 1 0 +github.com/gocraft/work/client.go:476.23,478.17 2 2 +github.com/gocraft/work/client.go:483.3,483.17 1 2 +github.com/gocraft/work/client.go:478.17,481.4 2 0 +github.com/gocraft/work/client.go:483.17,485.18 2 1 +github.com/gocraft/work/client.go:489.4,493.18 4 1 +github.com/gocraft/work/client.go:485.18,488.5 2 0 +github.com/gocraft/work/client.go:493.18,496.5 2 0 +github.com/gocraft/work/client.go:500.9,502.3 1 1 +github.com/gocraft/work/client.go:507.68,509.16 2 1 +github.com/gocraft/work/client.go:512.2,512.9 1 1 +github.com/gocraft/work/client.go:515.2,515.12 1 1 +github.com/gocraft/work/client.go:509.16,511.3 1 0 +github.com/gocraft/work/client.go:512.9,514.3 1 0 +github.com/gocraft/work/client.go:519.98,530.22 9 9 +github.com/gocraft/work/client.go:534.2,536.16 3 9 +github.com/gocraft/work/client.go:541.2,541.31 1 9 +github.com/gocraft/work/client.go:530.22,532.3 1 0 +github.com/gocraft/work/client.go:536.16,539.3 2 0 +github.com/gocraft/work/client.go:550.80,554.15 3 24 +github.com/gocraft/work/client.go:558.2,559.16 2 24 +github.com/gocraft/work/client.go:564.2,566.65 2 24 +github.com/gocraft/work/client.go:571.2,571.37 1 24 +github.com/gocraft/work/client.go:581.2,582.16 2 24 +github.com/gocraft/work/client.go:587.2,587.35 1 24 +github.com/gocraft/work/client.go:554.15,556.3 1 0 +github.com/gocraft/work/client.go:559.16,562.3 2 0 +github.com/gocraft/work/client.go:566.65,569.3 2 0 +github.com/gocraft/work/client.go:571.37,573.17 2 95 +github.com/gocraft/work/client.go:578.3,578.30 1 95 +github.com/gocraft/work/client.go:573.17,576.4 2 0 +github.com/gocraft/work/client.go:582.16,585.3 2 0 +github.com/gocraft/work/enqueue.go:23.64,24.17 1 24 +github.com/gocraft/work/enqueue.go:28.2,35.3 1 24 +github.com/gocraft/work/enqueue.go:24.17,25.51 1 0 +github.com/gocraft/work/enqueue.go:40.87,49.16 3 65 +github.com/gocraft/work/enqueue.go:53.2,56.76 3 65 +github.com/gocraft/work/enqueue.go:60.2,60.56 1 65 +github.com/gocraft/work/enqueue.go:64.2,64.17 1 65 +github.com/gocraft/work/enqueue.go:49.16,51.3 1 0 +github.com/gocraft/work/enqueue.go:56.76,58.3 1 0 +github.com/gocraft/work/enqueue.go:60.56,62.3 1 0 +github.com/gocraft/work/enqueue.go:68.120,77.16 3 11 +github.com/gocraft/work/enqueue.go:81.2,90.16 5 11 +github.com/gocraft/work/enqueue.go:94.2,94.56 1 11 +github.com/gocraft/work/enqueue.go:98.2,98.26 1 11 +github.com/gocraft/work/enqueue.go:77.16,79.3 1 0 +github.com/gocraft/work/enqueue.go:90.16,92.3 1 0 +github.com/gocraft/work/enqueue.go:94.56,96.3 1 0 +github.com/gocraft/work/enqueue.go:107.93,109.2 1 9 +github.com/gocraft/work/enqueue.go:112.126,114.2 1 8 +github.com/gocraft/work/enqueue.go:122.129,124.16 2 16 +github.com/gocraft/work/enqueue.go:128.2,130.31 2 16 +github.com/gocraft/work/enqueue.go:133.2,133.17 1 3 +github.com/gocraft/work/enqueue.go:124.16,126.3 1 0 +github.com/gocraft/work/enqueue.go:130.31,132.3 1 13 +github.com/gocraft/work/enqueue.go:138.162,140.16 2 8 +github.com/gocraft/work/enqueue.go:144.2,150.31 3 8 +github.com/gocraft/work/enqueue.go:153.2,153.17 1 2 +github.com/gocraft/work/enqueue.go:140.16,142.3 1 0 +github.com/gocraft/work/enqueue.go:150.31,152.3 1 6 +github.com/gocraft/work/enqueue.go:156.74,164.8 6 100 +github.com/gocraft/work/enqueue.go:169.2,169.14 1 100 +github.com/gocraft/work/enqueue.go:179.2,179.12 1 100 +github.com/gocraft/work/enqueue.go:164.8,165.14 1 64 +github.com/gocraft/work/enqueue.go:165.14,167.4 1 63 +github.com/gocraft/work/enqueue.go:169.14,170.85 1 37 +github.com/gocraft/work/enqueue.go:174.3,176.17 3 37 +github.com/gocraft/work/enqueue.go:170.85,172.4 1 0 +github.com/gocraft/work/enqueue.go:184.141,186.19 2 24 +github.com/gocraft/work/enqueue.go:191.2,192.16 2 24 +github.com/gocraft/work/enqueue.go:196.2,206.16 3 24 +github.com/gocraft/work/enqueue.go:210.2,210.50 1 24 +github.com/gocraft/work/enqueue.go:244.2,244.28 1 24 +github.com/gocraft/work/enqueue.go:186.19,189.3 2 17 +github.com/gocraft/work/enqueue.go:192.16,194.3 1 0 +github.com/gocraft/work/enqueue.go:206.16,208.3 1 0 +github.com/gocraft/work/enqueue.go:210.50,214.57 3 24 +github.com/gocraft/work/enqueue.go:218.3,224.21 6 24 +github.com/gocraft/work/enqueue.go:234.3,234.19 1 24 +github.com/gocraft/work/enqueue.go:241.3,241.54 1 24 +github.com/gocraft/work/enqueue.go:214.57,216.4 1 0 +github.com/gocraft/work/enqueue.go:224.21,228.4 1 17 +github.com/gocraft/work/enqueue.go:228.9,232.4 1 7 +github.com/gocraft/work/enqueue.go:234.19,239.4 3 8 +github.com/gocraft/work/log.go:5.38,7.2 1 31 diff --git a/go.mod b/go.mod index 224eab98..a16ce294 100644 --- a/go.mod +++ b/go.mod @@ -15,13 +15,11 @@ require ( github.com/garyburd/redigo v1.6.0 // indirect github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0 github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b - github.com/gocraft/work v0.5.1 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/gomodule/redigo v2.0.0+incompatible github.com/jrallison/go-workers v0.0.0-20180112190529-dbf81d0b75bb github.com/kr/pretty v0.2.0 // indirect github.com/orfjackal/nanospec.go v0.0.0-20120727230329-de4694c1d701 // indirect - github.com/robfig/cron v1.2.0 // indirect github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.5.1 github.com/youtube/vitess v2.1.1+incompatible // indirect diff --git a/go.sum b/go.sum index 63aa5f0a..5bfe9d86 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0 h1:pKjeDsx7HGGbjr7V github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0/go.mod h1:rWibcVfwbUxi/QXW84U7vNTcIcZFd6miwbt8ritxh/Y= github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b h1:g2Qcs0B+vOQE1L3a7WQ/JUUSzJnHbTz14qkJSqEWcF4= github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b/go.mod h1:Ag7UMbZNGrnHwaXPJOUKJIVgx4QOWMOWZngrvsN6qak= -github.com/gocraft/work v0.5.1 h1:3bRjMiOo6N4zcRgZWV3Y7uX7R22SF+A9bPTk4xRXr34= -github.com/gocraft/work v0.5.1/go.mod h1:pc3n9Pb5FAESPPGfM0nL+7Q1xtgtRnF8rr/azzhQVlM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= @@ -41,10 +39,9 @@ github.com/orfjackal/nanospec.go v0.0.0-20120727230329-de4694c1d701 h1:yOXfzNV7q github.com/orfjackal/nanospec.go v0.0.0-20120727230329-de4694c1d701/go.mod h1:VtBIF1XX0c1nKkeAPk8i4aXkYopqQgfDqolHUIHPwNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= -github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= diff --git a/heartbeater.go b/heartbeater.go index ccc229c4..1de76585 100644 --- a/heartbeater.go +++ b/heartbeater.go @@ -73,7 +73,7 @@ func (h *workerPoolHeartbeater) stop() { func (h *workerPoolHeartbeater) loop() { h.startedAt = nowEpochSeconds() h.heartbeat() // do it right away - ticker := time.Tick(h.beatPeriod) + ticker := time.NewTicker(h.beatPeriod).C for { select { case <-h.stopChan: diff --git a/heartbeater_test.go b/heartbeater_test.go index 2af2d2a9..c72a03fe 100644 --- a/heartbeater_test.go +++ b/heartbeater_test.go @@ -9,7 +9,7 @@ import ( ) func TestHeartbeater(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" tMock := int64(1425263409) diff --git a/observer.go b/observer.go index 5c96ac39..2c28cf48 100644 --- a/observer.go +++ b/observer.go @@ -124,7 +124,7 @@ func (o *observer) loop() { // Every tick we'll update redis if necessary // We don't update it on every job because the only purpose of this data is for humans to inspect the system, // and a fast worker could move onto new jobs every few ms. - ticker := time.Tick(1000 * time.Millisecond) + ticker := time.NewTicker(1000 * time.Millisecond).C for { select { diff --git a/observer_test.go b/observer_test.go index d95e729b..e25d44a8 100644 --- a/observer_test.go +++ b/observer_test.go @@ -9,7 +9,7 @@ import ( ) func TestObserverStarted(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" tMock := int64(1425263401) @@ -31,7 +31,7 @@ func TestObserverStarted(t *testing.T) { } func TestObserverStartedDone(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" tMock := int64(1425263401) @@ -50,7 +50,7 @@ func TestObserverStartedDone(t *testing.T) { } func TestObserverCheckin(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" observer := newObserver(ns, pool, "abcd") @@ -77,7 +77,7 @@ func TestObserverCheckin(t *testing.T) { } func TestObserverCheckinFromJob(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" observer := newObserver(ns, pool, "abcd") diff --git a/periodic_enqueuer.go b/periodic_enqueuer.go index ae957e7f..ad91615a 100644 --- a/periodic_enqueuer.go +++ b/periodic_enqueuer.go @@ -1,8 +1,9 @@ package work import ( + "crypto/rand" "fmt" - "math/rand" + "math/big" "time" "github.com/gomodule/redigo/redis" @@ -15,12 +16,11 @@ const ( ) type periodicEnqueuer struct { - namespace string - pool *redis.Pool - periodicJobs []*periodicJob - scheduledPeriodicJobs []*scheduledPeriodicJob - stopChan chan struct{} - doneStoppingChan chan struct{} + namespace string + pool *redis.Pool + periodicJobs []*periodicJob + stopChan chan struct{} + doneStoppingChan chan struct{} } type periodicJob struct { @@ -29,12 +29,6 @@ type periodicJob struct { schedule cron.Schedule } -type scheduledPeriodicJob struct { - scheduledAt time.Time - scheduledAtEpoch int64 - *periodicJob -} - func newPeriodicEnqueuer(namespace string, pool *redis.Pool, periodicJobs []*periodicJob) *periodicEnqueuer { return &periodicEnqueuer{ namespace: namespace, @@ -56,7 +50,11 @@ func (pe *periodicEnqueuer) stop() { func (pe *periodicEnqueuer) loop() { // Begin reaping periodically - timer := time.NewTimer(periodicEnqueuerSleep + time.Duration(rand.Intn(30))*time.Second) + n, err := rand.Int(rand.Reader, big.NewInt(30)) + if err != nil { + panic(err) + } + timer := time.NewTimer(periodicEnqueuerSleep + time.Duration(n.Int64())*time.Second) defer timer.Stop() if pe.shouldEnqueue() { @@ -72,7 +70,12 @@ func (pe *periodicEnqueuer) loop() { pe.doneStoppingChan <- struct{}{} return case <-timer.C: - timer.Reset(periodicEnqueuerSleep + time.Duration(rand.Intn(30))*time.Second) + n, err := rand.Int(rand.Reader, big.NewInt(30)) + if err != nil { + panic(err) + } + + timer.Reset(periodicEnqueuerSleep + time.Duration(n.Int64())*time.Second) if pe.shouldEnqueue() { err := pe.enqueue() if err != nil { diff --git a/periodic_enqueuer_test.go b/periodic_enqueuer_test.go index e460a041..913766bb 100644 --- a/periodic_enqueuer_test.go +++ b/periodic_enqueuer_test.go @@ -10,7 +10,7 @@ import ( ) func TestPeriodicEnqueuer(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -98,7 +98,7 @@ func TestPeriodicEnqueuer(t *testing.T) { } func TestPeriodicEnqueuerSpawn(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) diff --git a/priority_sampler.go b/priority_sampler.go index a31d017f..a81f084d 100644 --- a/priority_sampler.go +++ b/priority_sampler.go @@ -1,7 +1,9 @@ package work import ( - "math/rand" + "crypto/rand" + "math" + "math/big" ) type prioritySampler struct { @@ -55,9 +57,13 @@ func (s *prioritySampler) sample() []sampleItem { // and see where the random number fits in the continuum. // If we find where it fits, sort the item to the next slot towards the front of the slice. for remaining > 1 { - // rn from [0 to sumRemaining) - rn := uint(rand.Uint32()) % sumRemaining + n, err := rand.Int(rand.Reader, big.NewInt(math.MaxUint32)) + if err != nil { + panic(err) + } + // rn from [0 to sumRemaining) + rn := uint(n.Uint64()) % sumRemaining prevSum := uint(0) for i := lenSamples - 1; i >= lastValidIdx; i-- { sample := s.samples[i] diff --git a/requeuer.go b/requeuer.go index 55fa4513..c05e5635 100644 --- a/requeuer.go +++ b/requeuer.go @@ -65,7 +65,7 @@ func (r *requeuer) loop() { // If we have 100 processes all running requeuers, // there's probably too much hitting redis. // So later on we'l have to implement exponential backoff - ticker := time.Tick(1000 * time.Millisecond) + ticker := time.NewTicker(1000 * time.Millisecond).C for { select { diff --git a/requeuer_test.go b/requeuer_test.go index 65418eca..5344da0c 100644 --- a/requeuer_test.go +++ b/requeuer_test.go @@ -7,7 +7,7 @@ import ( ) func TestRequeue(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -50,7 +50,7 @@ func TestRequeue(t *testing.T) { } func TestRequeueUnknown(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) diff --git a/run.go b/run.go index c6f38615..ea23579e 100644 --- a/run.go +++ b/run.go @@ -48,7 +48,5 @@ func runJob(job *Job, ctxType reflect.Type, middleware []*middlewareHandler, jt } }() - returnError = next() - - return + return returnCtx, next() } diff --git a/time.go b/time.go index a4548364..9b09234f 100644 --- a/time.go +++ b/time.go @@ -18,8 +18,3 @@ func setNowEpochSecondsMock(t int64) { func resetNowEpochSecondsMock() { nowMock = 0 } - -// convert epoch seconds to a time -func epochSecondsToTime(t int64) time.Time { - return time.Time{} -} diff --git a/webui/webui_test.go b/webui/webui_test.go index 6bffc745..850ac901 100644 --- a/webui/webui_test.go +++ b/webui/webui_test.go @@ -15,7 +15,7 @@ import ( ) func TestWebUIStartStop(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -27,7 +27,7 @@ func TestWebUIStartStop(t *testing.T) { type TestContext struct{} func TestWebUIQueues(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -83,7 +83,7 @@ func TestWebUIQueues(t *testing.T) { } func TestWebUIWorkerPools(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -121,7 +121,7 @@ func TestWebUIWorkerPools(t *testing.T) { } func TestWebUIBusyWorkers(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -183,7 +183,7 @@ func TestWebUIBusyWorkers(t *testing.T) { } func TestWebUIRetryJobs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) @@ -226,7 +226,7 @@ func TestWebUIRetryJobs(t *testing.T) { } func TestWebUIScheduledJobs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) @@ -259,12 +259,13 @@ func TestWebUIScheduledJobs(t *testing.T) { } func TestWebUIDeadJobs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) enqueuer := work.NewEnqueuer(ns, pool) _, err := enqueuer.Enqueue("wat", nil) + assert.Nil(t, err) _, err = enqueuer.Enqueue("wat", nil) assert.Nil(t, err) @@ -347,12 +348,13 @@ func TestWebUIDeadJobs(t *testing.T) { } func TestWebUIDeadJobsDeleteRetryAll(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" cleanKeyspace(ns, pool) enqueuer := work.NewEnqueuer(ns, pool) _, err := enqueuer.Enqueue("wat", nil) + assert.Nil(t, err) _, err = enqueuer.Enqueue("wat", nil) assert.Nil(t, err) @@ -448,14 +450,14 @@ func TestWebUIDeadJobsDeleteRetryAll(t *testing.T) { } func TestWebUIAssets(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "testwork" s := NewServer(ns, pool, ":6666") recorder := httptest.NewRecorder() request, _ := http.NewRequest("GET", "/", nil) s.router.ServeHTTP(recorder, request) - body := string(recorder.Body.Bytes()) + body := recorder.Body.String() assert.Regexp(t, "html", body) recorder = httptest.NewRecorder() @@ -463,13 +465,13 @@ func TestWebUIAssets(t *testing.T) { s.router.ServeHTTP(recorder, request) } -func newTestPool(addr string) *redis.Pool { +func newTestPool() *redis.Pool { return &redis.Pool{ MaxActive: 3, MaxIdle: 3, IdleTimeout: 240 * time.Second, Dial: func() (redis.Conn, error) { - return redis.Dial("tcp", addr) + return redis.Dial("tcp", ":6379") }, Wait: true, } diff --git a/worker.go b/worker.go index d7578334..cb021c46 100644 --- a/worker.go +++ b/worker.go @@ -1,8 +1,9 @@ package work import ( + "crypto/rand" "fmt" - "math/rand" + "math/big" "reflect" "time" @@ -32,7 +33,7 @@ type worker struct { doneDrainingChan chan struct{} } -func newWorker(namespace string, poolID string, pool *redis.Pool, contextType reflect.Type, middleware []*middlewareHandler, jobTypes map[string]*jobType, sleepBackoffs []int64) *worker { +func newWorker(namespace string, poolID string, pool *redis.Pool, contextType reflect.Type, jobTypes map[string]*jobType, sleepBackoffs []int64) *worker { workerID := makeIdentifier() ob := newObserver(namespace, pool, workerID) @@ -57,7 +58,7 @@ func newWorker(namespace string, poolID string, pool *redis.Pool, contextType re doneDrainingChan: make(chan struct{}), } - w.updateMiddlewareAndJobTypes(middleware, jobTypes) + w.updateMiddlewareAndJobTypes(nil, jobTypes) return w } @@ -280,7 +281,7 @@ func (w *worker) removeJobFromInProgress(job *Job, fate terminateOp) { type terminateOp func(conn redis.Conn) -func terminateOnly(_ redis.Conn) { return } +func terminateOnly(_ redis.Conn) {} func terminateAndRetry(w *worker, jt *jobType, job *Job) terminateOp { rawJSON, err := job.serialize() if err != nil { @@ -323,5 +324,10 @@ func (w *worker) jobFate(jt *jobType, job *Job) terminateOp { // Default algorithm returns an fastly increasing backoff counter which grows in an unbounded fashion func defaultBackoffCalculator(job *Job) int64 { fails := job.Fails - return (fails * fails * fails * fails) + 15 + (rand.Int63n(30) * (fails + 1)) + n, err := rand.Int(rand.Reader, big.NewInt(30)) + if err != nil { + panic(err) + } + + return (fails * fails * fails * fails) + 15 + (n.Int64() * (fails + 1)) } diff --git a/worker_pool.go b/worker_pool.go index d83c7b79..ab4afd87 100644 --- a/worker_pool.go +++ b/worker_pool.go @@ -109,7 +109,7 @@ func NewWorkerPoolWithOptions(ctx interface{}, concurrency uint, namespace strin } for i := uint(0); i < wp.concurrency; i++ { - w := newWorker(wp.namespace, wp.workerPoolID, wp.pool, wp.contextType, nil, wp.jobTypes, wp.sleepBackoffs) + w := newWorker(wp.namespace, wp.workerPoolID, wp.pool, wp.contextType, wp.jobTypes, wp.sleepBackoffs) wp.workers = append(wp.workers, w) } diff --git a/worker_pool_test.go b/worker_pool_test.go index 911aa9dc..b2c47997 100644 --- a/worker_pool_test.go +++ b/worker_pool_test.go @@ -12,7 +12,6 @@ import ( ) type tstCtx struct { - a int bytes.Buffer } @@ -31,7 +30,7 @@ func TestWorkerPoolHandlerValidations(t *testing.T) { {func(c *tstCtx, j *Job) error { return nil }, true}, {func(c *tstCtx, j *Job) {}, false}, {func(c *tstCtx, j *Job) string { return "" }, false}, - {func(c *tstCtx, j *Job) (error, string) { return nil, "" }, false}, + {func(c *tstCtx, j *Job) (string, error) { return "", nil }, false}, {func(c *tstCtx) error { return nil }, false}, {func(c tstCtx, j *Job) error { return nil }, false}, {func() error { return nil }, false}, @@ -56,7 +55,7 @@ func TestWorkerPoolMiddlewareValidations(t *testing.T) { {func(c *tstCtx, j *Job) error { return nil }, false}, {func(c *tstCtx, j *Job, n NextMiddlewareFunc) {}, false}, {func(c *tstCtx, j *Job, n NextMiddlewareFunc) string { return "" }, false}, - {func(c *tstCtx, j *Job, n NextMiddlewareFunc) (error, string) { return nil, "" }, false}, + {func(c *tstCtx, j *Job, n NextMiddlewareFunc) (string, error) { return "", nil }, false}, {func(c *tstCtx, n NextMiddlewareFunc) error { return nil }, false}, {func(c tstCtx, j *Job, n NextMiddlewareFunc) error { return nil }, false}, {func() error { return nil }, false}, @@ -73,7 +72,7 @@ func TestWorkerPoolMiddlewareValidations(t *testing.T) { } func TestWorkerPoolStartStop(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" wp := NewWorkerPool(TestContext{}, 10, ns, pool) wp.Start() @@ -85,7 +84,7 @@ func TestWorkerPoolStartStop(t *testing.T) { } func TestWorkerPoolValidations(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" wp := NewWorkerPool(TestContext{}, 10, ns, pool) @@ -115,7 +114,7 @@ func TestWorkerPoolValidations(t *testing.T) { } func TestWorkersPoolRunSingleThreaded(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" numJobs, concurrency, sleepTime := 5, 5, 2 @@ -158,7 +157,7 @@ func TestWorkersPoolRunSingleThreaded(t *testing.T) { } func TestWorkerPoolPauseSingleThreadedJobs(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns, job1 := "work", "job1" numJobs, concurrency, sleepTime := 5, 5, 2 wp := setupTestWorkerPool(pool, ns, job1, concurrency, JobOptions{Priority: 1, MaxConcurrency: 1}) diff --git a/worker_test.go b/worker_test.go index f1bddf77..11099249 100644 --- a/worker_test.go +++ b/worker_test.go @@ -12,7 +12,7 @@ import ( ) func TestWorkerBasics(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" job2 := "job2" @@ -61,7 +61,7 @@ func TestWorkerBasics(t *testing.T) { _, err = enqueuer.Enqueue(job3, Q{"a": 3}) assert.Nil(t, err) - w := newWorker(ns, "1", pool, tstCtxType, nil, jobTypes, nil) + w := newWorker(ns, "1", pool, tstCtxType, jobTypes, nil) w.start() w.drain() w.stop() @@ -89,7 +89,7 @@ func TestWorkerBasics(t *testing.T) { } func TestWorkerInProgress(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" deleteQueue(pool, ns, job1) @@ -111,7 +111,7 @@ func TestWorkerInProgress(t *testing.T) { _, err := enqueuer.Enqueue(job1, Q{"a": 1}) assert.Nil(t, err) - w := newWorker(ns, "1", pool, tstCtxType, nil, jobTypes, nil) + w := newWorker(ns, "1", pool, tstCtxType, jobTypes, nil) w.start() // instead of w.forceIter(), we'll wait for 10 milliseconds to let the job start @@ -142,7 +142,7 @@ func TestWorkerInProgress(t *testing.T) { } func TestWorkerRetry(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" deleteQueue(pool, ns, job1) @@ -162,7 +162,7 @@ func TestWorkerRetry(t *testing.T) { enqueuer := NewEnqueuer(ns, pool) _, err := enqueuer.Enqueue(job1, Q{"a": 1}) assert.Nil(t, err) - w := newWorker(ns, "1", pool, tstCtxType, nil, jobTypes, nil) + w := newWorker(ns, "1", pool, tstCtxType, jobTypes, nil) w.start() w.drain() w.stop() @@ -189,7 +189,7 @@ func TestWorkerRetry(t *testing.T) { // Check if a custom backoff function functions functionally. func TestWorkerRetryWithCustomBackoff(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" deleteQueue(pool, ns, job1) @@ -214,7 +214,7 @@ func TestWorkerRetryWithCustomBackoff(t *testing.T) { enqueuer := NewEnqueuer(ns, pool) _, err := enqueuer.Enqueue(job1, Q{"a": 1}) assert.Nil(t, err) - w := newWorker(ns, "1", pool, tstCtxType, nil, jobTypes, nil) + w := newWorker(ns, "1", pool, tstCtxType, jobTypes, nil) w.start() w.drain() w.stop() @@ -239,7 +239,7 @@ func TestWorkerRetryWithCustomBackoff(t *testing.T) { } func TestWorkerDead(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" job2 := "job2" @@ -271,7 +271,7 @@ func TestWorkerDead(t *testing.T) { assert.Nil(t, err) _, err = enqueuer.Enqueue(job2, nil) assert.Nil(t, err) - w := newWorker(ns, "1", pool, tstCtxType, nil, jobTypes, nil) + w := newWorker(ns, "1", pool, tstCtxType, jobTypes, nil) w.start() w.drain() w.stop() @@ -302,7 +302,7 @@ func TestWorkerDead(t *testing.T) { } func TestWorkersPaused(t *testing.T) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" job1 := "job1" deleteQueue(pool, ns, job1) @@ -324,7 +324,7 @@ func TestWorkersPaused(t *testing.T) { _, err := enqueuer.Enqueue(job1, Q{"a": 1}) assert.Nil(t, err) - w := newWorker(ns, "1", pool, tstCtxType, nil, jobTypes, nil) + w := newWorker(ns, "1", pool, tstCtxType, jobTypes, nil) // pause the jobs prior to starting err = pauseJobs(ns, job1, pool) assert.Nil(t, err) @@ -381,7 +381,7 @@ func TestStop(t *testing.T) { } func BenchmarkJobProcessing(b *testing.B) { - pool := newTestPool(":6379") + pool := newTestPool() ns := "work" cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -405,13 +405,13 @@ func BenchmarkJobProcessing(b *testing.B) { wp.Stop() } -func newTestPool(addr string) *redis.Pool { +func newTestPool() *redis.Pool { return &redis.Pool{ MaxActive: 10, MaxIdle: 10, IdleTimeout: 240 * time.Second, Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) + c, err := redis.Dial("tcp", ":6379") if err != nil { return nil, err } @@ -598,9 +598,9 @@ type emptyCtx struct{} // https://github.com/gocraft/work/issues/24 func TestWorkerPoolStop(t *testing.T) { ns := "will_it_end" - pool := newTestPool(":6379") + pool := newTestPool() var started, stopped int32 - num_iters := 30 + numIters := 30 wp := NewWorkerPool(emptyCtx{}, 2, ns, pool) @@ -613,7 +613,7 @@ func TestWorkerPoolStop(t *testing.T) { var enqueuer = NewEnqueuer(ns, pool) - for i := 0; i <= num_iters; i++ { + for i := 0; i <= numIters; i++ { enqueuer.Enqueue("sample_job", Q{}) } @@ -627,7 +627,7 @@ func TestWorkerPoolStop(t *testing.T) { t.Errorf("Expected that jobs were finished and not killed while processing (started=%d, stopped=%d)", started, stopped) } - if started >= int32(num_iters) { + if started >= int32(numIters) { t.Errorf("Expected that jobs queue was not completely emptied.") } } From 73d6f7ac34b9bc02c557cb8c717707bf5240c847 Mon Sep 17 00:00:00 2001 From: ardhi Date: Fri, 18 Sep 2020 13:58:26 +0700 Subject: [PATCH 2/7] Remove benches since the external worker have deps problem --- benches/bench_goworker/main.go | 122 ---------------------------- benches/bench_goworkers/main.go | 129 ----------------------------- benches/bench_jobs/main.go | 138 -------------------------------- go.mod | 20 +---- go.sum | 47 ++--------- 5 files changed, 11 insertions(+), 445 deletions(-) delete mode 100644 benches/bench_goworker/main.go delete mode 100644 benches/bench_goworkers/main.go delete mode 100644 benches/bench_jobs/main.go diff --git a/benches/bench_goworker/main.go b/benches/bench_goworker/main.go deleted file mode 100644 index faf41356..00000000 --- a/benches/bench_goworker/main.go +++ /dev/null @@ -1,122 +0,0 @@ -package main - -import ( - "fmt" - "os" - "sync/atomic" - "time" - - "github.com/benmanns/goworker" - "github.com/gocraft/health" - "github.com/gomodule/redigo/redis" -) - -func myJob(queue string, args ...interface{}) error { - atomic.AddInt64(&totcount, 1) - //fmt.Println("job! ", queue) - return nil -} - -var namespace = "bench_test" -var pool = newPool(":6379") - -// go run *.go -queues="myqueue,myqueue2,myqueue3,myqueue4,myqueue5" -namespace="bench_test:" -concurrency=50 -use-nuber -func main() { - - stream := health.NewStream().AddSink(&health.WriterSink{os.Stdout}) - stream.Event("wat") - cleanKeyspace() - - queues := []string{"myqueue", "myqueue2", "myqueue3", "myqueue4", "myqueue5"} - numJobs := 100000 / len(queues) - - job := stream.NewJob("enqueue_all") - for _, q := range queues { - enqueueJobs(q, numJobs) - } - job.Complete(health.Success) - - goworker.Register("MyClass", myJob) - - go monitor() - - // Blocks until process is told to exit via unix signal - goworker.Work() -} - -var totcount int64 - -func monitor() { - t := time.Tick(1 * time.Second) - - curT := 0 - c1 := int64(0) - c2 := int64(0) - prev := int64(0) - -DALOOP: - for range t { - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v - } - - fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) - os.Exit(0) -} - -func enqueueJobs(queue string, count int) { - conn := pool.Get() - defer conn.Close() - - for i := 0; i < count; i++ { - //workers.Enqueue(queue, "Foo", []int{i}) - conn.Do("RPUSH", "bench_test:queue:"+queue, `{"class":"MyClass","args":[]}`) - } -} - -func cleanKeyspace() { - conn := pool.Get() - defer conn.Close() - - keys, err := redis.Strings(conn.Do("KEYS", namespace+"*")) - if err != nil { - panic("could not get keys: " + err.Error()) - } - for _, k := range keys { - //fmt.Println("deleting ", k) - if _, err := conn.Do("DEL", k); err != nil { - panic("could not del: " + err.Error()) - } - } -} - -func newPool(addr string) *redis.Pool { - return &redis.Pool{ - MaxActive: 3, - MaxIdle: 3, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) - if err != nil { - return nil, err - } - return c, nil - //return redis.NewLoggingConn(c, log.New(os.Stdout, "", 0), "redis"), err - }, - Wait: true, - //TestOnBorrow: func(c redis.Conn, t time.Time) error { - // _, err := c.Do("PING") - // return err - //}, - } -} diff --git a/benches/bench_goworkers/main.go b/benches/bench_goworkers/main.go deleted file mode 100644 index 6e51df7c..00000000 --- a/benches/bench_goworkers/main.go +++ /dev/null @@ -1,129 +0,0 @@ -package main - -import ( - "fmt" - "os" - "sync/atomic" - "time" - - "github.com/gocraft/health" - "github.com/gomodule/redigo/redis" - "github.com/jrallison/go-workers" -) - -func myJob(m *workers.Msg) { - atomic.AddInt64(&totcount, 1) -} - -var namespace = "bench_test" -var pool = newPool(":6379") - -func main() { - - stream := health.NewStream().AddSink(&health.WriterSink{os.Stdout}) - stream.Event("wat") - cleanKeyspace() - - workers.Configure(map[string]string{ - // location of redis instance - "server": "localhost:6379", - // instance of the database - "database": "0", - // number of connections to keep open with redis - "pool": "10", - // unique process id for this instance of workers (for proper recovery of inprogress jobs on crash) - "process": "1", - "namespace": namespace, - }) - workers.Middleware = &workers.Middlewares{} - - queues := []string{"myqueue", "myqueue2", "myqueue3", "myqueue4", "myqueue5"} - numJobs := 100000 / len(queues) - - job := stream.NewJob("enqueue_all") - for _, q := range queues { - enqueueJobs(q, numJobs) - } - job.Complete(health.Success) - - for _, q := range queues { - workers.Process(q, myJob, 10) - } - - go monitor() - - // Blocks until process is told to exit via unix signal - workers.Run() -} - -var totcount int64 - -func monitor() { - t := time.Tick(1 * time.Second) - - curT := 0 - c1 := int64(0) - c2 := int64(0) - prev := int64(0) - -DALOOP: - for range t { - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - } - - fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) - os.Exit(0) -} - -func enqueueJobs(queue string, count int) { - for i := 0; i < count; i++ { - workers.Enqueue(queue, "Foo", []int{i}) - } -} - -func cleanKeyspace() { - conn := pool.Get() - defer conn.Close() - - keys, err := redis.Strings(conn.Do("KEYS", namespace+"*")) - if err != nil { - panic("could not get keys: " + err.Error()) - } - for _, k := range keys { - //fmt.Println("deleting ", k) - if _, err := conn.Do("DEL", k); err != nil { - panic("could not del: " + err.Error()) - } - } -} - -func newPool(addr string) *redis.Pool { - return &redis.Pool{ - MaxActive: 3, - MaxIdle: 3, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) - if err != nil { - return nil, err - } - return c, nil - //return redis.NewLoggingConn(c, log.New(os.Stdout, "", 0), "redis"), err - }, - Wait: true, - //TestOnBorrow: func(c redis.Conn, t time.Time) error { - // _, err := c.Do("PING") - // return err - //}, - } -} diff --git a/benches/bench_jobs/main.go b/benches/bench_jobs/main.go deleted file mode 100644 index 7676348c..00000000 --- a/benches/bench_jobs/main.go +++ /dev/null @@ -1,138 +0,0 @@ -package main - -import ( - "fmt" - "os" - "sync/atomic" - "time" - - "github.com/albrow/jobs" - "github.com/gocraft/health" - "github.com/gomodule/redigo/redis" -) - -var namespace = "jobs" -var pool = newPool(":6379") - -func epsilonHandler(i int) error { - atomic.AddInt64(&totcount, 1) - return nil -} - -func main() { - stream := health.NewStream().AddSink(&health.WriterSink{os.Stdout}) - cleanKeyspace() - - queueNames := []string{"myqueue", "myqueue2", "myqueue3", "myqueue4", "myqueue5"} - queues := []*jobs.Type{} - - for _, qn := range queueNames { - q, err := jobs.RegisterType(qn, 3, epsilonHandler) - if err != nil { - panic(err) - } - queues = append(queues, q) - } - - job := stream.NewJob("enqueue_all") - - numJobs := 40000 / len(queues) - for _, q := range queues { - for i := 0; i < numJobs; i++ { - _, err := q.Schedule(100, time.Now(), i) - if err != nil { - panic(err) - } - } - } - - job.Complete(health.Success) - - go monitor() - - job = stream.NewJob("run_all") - pool, err := jobs.NewPool(&jobs.PoolConfig{ - // NumWorkers: 1000, - // BatchSize: 3000, - }) - if err != nil { - panic(err) - } - defer func() { - pool.Close() - if err := pool.Wait(); err != nil { - panic(err) - } - }() - if err := pool.Start(); err != nil { - panic(err) - } - job.Complete(health.Success) - select {} -} - -var totcount int64 - -func monitor() { - t := time.Tick(1 * time.Second) - - curT := 0 - c1 := int64(0) - c2 := int64(0) - prev := int64(0) - -DALOOP: - for range t { - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v - } - fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) - os.Exit(0) -} - -func cleanKeyspace() { - conn := pool.Get() - defer conn.Close() - - keys, err := redis.Strings(conn.Do("KEYS", namespace+"*")) - if err != nil { - panic("could not get keys: " + err.Error()) - } - for _, k := range keys { - //fmt.Println("deleting ", k) - if _, err := conn.Do("DEL", k); err != nil { - panic("could not del: " + err.Error()) - } - } -} - -func newPool(addr string) *redis.Pool { - return &redis.Pool{ - MaxActive: 20, - MaxIdle: 20, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) - if err != nil { - return nil, err - } - return c, nil - //return redis.NewLoggingConn(c, log.New(os.Stdout, "", 0), "redis"), err - }, - Wait: true, - //TestOnBorrow: func(c redis.Conn, t time.Time) error { - // _, err := c.Do("PING") - // return err - //}, - } -} diff --git a/go.mod b/go.mod index a16ce294..58fe3633 100644 --- a/go.mod +++ b/go.mod @@ -3,25 +3,11 @@ module github.com/gocraft/work go 1.14 require ( - github.com/albrow/jobs v0.4.2 - github.com/benmanns/goworker v0.1.3 - github.com/bitly/go-simplejson v0.5.0 // indirect - github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/braintree/manners v0.0.0-20160418043613-82a8879fc5fd - github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect - github.com/customerio/gospec v0.0.0-20130710230057-a5cc0e48aa39 // indirect - github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect - github.com/garyburd/redigo v1.6.0 // indirect github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0 github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect - github.com/gomodule/redigo v2.0.0+incompatible - github.com/jrallison/go-workers v0.0.0-20180112190529-dbf81d0b75bb - github.com/kr/pretty v0.2.0 // indirect - github.com/orfjackal/nanospec.go v0.0.0-20120727230329-de4694c1d701 // indirect + github.com/gomodule/redigo v1.8.2 + github.com/google/uuid v1.1.2 github.com/robfig/cron/v3 v3.0.1 - github.com/stretchr/testify v1.5.1 - github.com/youtube/vitess v2.1.1+incompatible // indirect - golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect + github.com/stretchr/testify v1.6.1 ) diff --git a/go.sum b/go.sum index 5bfe9d86..679a2dfa 100644 --- a/go.sum +++ b/go.sum @@ -1,42 +1,15 @@ -github.com/albrow/jobs v0.4.2 h1:AhhNNgtnOz3h+Grt6uuRJP+uj/AVq+ZhIBY8Mzkf4TM= -github.com/albrow/jobs v0.4.2/go.mod h1:e4sWh7D1DxPbpxrzJhNo/cMARAljpTYF/osgh2j3+r8= -github.com/benmanns/goworker v0.1.3 h1:ekwn7WiKsn8oUOKfbHDqsA6g5bXz/uEZ9AdnKgtAECY= -github.com/benmanns/goworker v0.1.3/go.mod h1:Gj3m7lTyCswE3+Kta7c79CMOmm5rHJmj2qh/GAmojJ4= -github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/braintree/manners v0.0.0-20160418043613-82a8879fc5fd h1:ePesaBzdTmoMQjwqRCLP2jY+jjWMBpwws/LEQdt1fMM= github.com/braintree/manners v0.0.0-20160418043613-82a8879fc5fd/go.mod h1:TNehV1AhBwtT7Bd+rh8G6MoGDbBLNs/sKdk3nvr4Yzg= -github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= -github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= -github.com/customerio/gospec v0.0.0-20130710230057-a5cc0e48aa39 h1:O0YTztXI3XeJXlFhSo4wNb0VBVqSgT+hi/CjNWKvMnY= -github.com/customerio/gospec v0.0.0-20130710230057-a5cc0e48aa39/go.mod h1:OzYUFhPuL2JbjwFwrv6CZs23uBawekc6OZs+g19F0mY= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 h1:RAV05c0xOkJ3dZGS0JFybxFKZ2WMLabgx3uXnd7rpGs= -github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0 h1:pKjeDsx7HGGbjr7VGI1HksxDJqSjaGED3cSw9GeSI98= github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0/go.mod h1:rWibcVfwbUxi/QXW84U7vNTcIcZFd6miwbt8ritxh/Y= github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b h1:g2Qcs0B+vOQE1L3a7WQ/JUUSzJnHbTz14qkJSqEWcF4= github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b/go.mod h1:Ag7UMbZNGrnHwaXPJOUKJIVgx4QOWMOWZngrvsN6qak= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/jrallison/go-workers v0.0.0-20180112190529-dbf81d0b75bb h1:y9LFhCM3gwK94Xz9/h7GcSVLteky9pFHEkP04AqQupA= -github.com/jrallison/go-workers v0.0.0-20180112190529-dbf81d0b75bb/go.mod h1:ziQRRNHCWZe0wVNzF8y8kCWpso0VMpqHJjB19DSenbE= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/orfjackal/nanospec.go v0.0.0-20120727230329-de4694c1d701 h1:yOXfzNV7qkZ3nf2NPqy4BMzlCmnQzIEbI1vuqKb2FkQ= -github.com/orfjackal/nanospec.go v0.0.0-20120727230329-de4694c1d701/go.mod h1:VtBIF1XX0c1nKkeAPk8i4aXkYopqQgfDqolHUIHPwNI= +github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= +github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= @@ -45,15 +18,11 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/youtube/vitess v2.1.1+incompatible h1:SE+P7DNX/jw5RHFs5CHRhZQjq402EJFCD33JhzQMdDw= -github.com/youtube/vitess v2.1.1+incompatible/go.mod h1:hpMim5/30F1r+0P8GGtB29d0gWHr0IZ5unS+CG0zMx8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U= -golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 097fc779303c25dcaadc9141955bc42f98eda197 Mon Sep 17 00:00:00 2001 From: ardhi Date: Fri, 18 Sep 2020 13:59:31 +0700 Subject: [PATCH 3/7] Allow some tests to run in parallel, need to figure out how to mock the time better before we able to run everything in parallel --- Makefile | 2 +- client_test.go | 47 +- dead_pool_reaper_test.go | 19 +- enqueue_test.go | 17 +- etc/out/profile.cov | 731 -------------------------------- heartbeater_test.go | 3 +- identifier_test.go | 2 + job_test.go | 10 + observer_test.go | 9 +- periodic_enqueuer_test.go | 7 +- priority_sampler_test.go | 1 + requeuer_test.go | 5 +- run_test.go | 10 + time.go | 4 +- webui/internal/assets/assets.go | 8 +- webui/webui_test.go | 37 +- worker_pool_test.go | 15 +- worker_test.go | 29 +- 18 files changed, 165 insertions(+), 791 deletions(-) delete mode 100644 etc/out/profile.cov diff --git a/Makefile b/Makefile index 210fa52d..8790bec9 100644 --- a/Makefile +++ b/Makefile @@ -27,5 +27,5 @@ lint-strict: test: mkdir -p ./etc/out - ENVIRONMENT=test go test -failfast -count 1 -timeout 30s -race -covermode=atomic -coverprofile=etc/out/profile.cov ./... && go tool cover -func=etc/out/profile.cov + ENVIRONMENT=test go test -failfast -count 1 -timeout 30s -covermode=atomic -coverprofile=etc/out/profile.cov ./... && go tool cover -func=etc/out/profile.cov diff --git a/client_test.go b/client_test.go index c43e3265..3079e5c1 100644 --- a/client_test.go +++ b/client_test.go @@ -6,14 +6,17 @@ import ( "time" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) type TestContext struct{} func TestClientWorkerPoolHeartbeats(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "TestClientWorkerPoolHeartbeats" + ns := uuid.New().String() cleanKeyspace(ns, pool) wp := NewWorkerPool(TestContext{}, 10, ns, pool) @@ -65,7 +68,7 @@ func TestClientWorkerPoolHeartbeats(t *testing.T) { func TestClientWorkerObservations(t *testing.T) { pool := newTestPool() - ns := "TestClientWorkerObservations" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -134,7 +137,7 @@ func TestClientWorkerObservations(t *testing.T) { func TestClientQueues(t *testing.T) { pool := newTestPool() - ns := "TestClientQueues" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -188,7 +191,7 @@ func TestClientQueues(t *testing.T) { func TestClientScheduledJobs(t *testing.T) { pool := newTestPool() - ns := "TestClientScheduledJobs" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -239,7 +242,7 @@ func TestClientScheduledJobs(t *testing.T) { func TestClientRetryJobs(t *testing.T) { pool := newTestPool() - ns := "TestClientRetryJobs" + ns := uuid.New().String() cleanKeyspace(ns, pool) setNowEpochSecondsMock(1425263409) @@ -278,7 +281,7 @@ func TestClientRetryJobs(t *testing.T) { func TestClientDeadJobs(t *testing.T) { pool := newTestPool() - ns := "TestClientDeadJobs" + ns := uuid.New().String() cleanKeyspace(ns, pool) setNowEpochSecondsMock(1425263409) @@ -332,8 +335,10 @@ func TestClientDeadJobs(t *testing.T) { } func TestClientDeleteDeadJob(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "TestClientDeleteDeadJob" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Insert a dead job: @@ -361,8 +366,10 @@ func TestClientDeleteDeadJob(t *testing.T) { } func TestClientRetryDeadJob(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "TestClientRetryDeadJob" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Insert a dead job: @@ -417,8 +424,10 @@ func TestClientRetryDeadJob(t *testing.T) { } func TestClientRetryDeadJobWithArgs(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Enqueue a job with arguments @@ -461,8 +470,10 @@ func TestClientRetryDeadJobWithArgs(t *testing.T) { } func TestClientDeleteAllDeadJobs(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Insert a dead job: @@ -488,7 +499,7 @@ func TestClientDeleteAllDeadJobs(t *testing.T) { func TestClientRetryAllDeadJobs(t *testing.T) { pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) setNowEpochSecondsMock(1425263409) @@ -545,8 +556,10 @@ func TestClientRetryAllDeadJobs(t *testing.T) { } func TestClientRetryAllDeadJobsBig(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) conn := pool.Get() @@ -614,8 +627,10 @@ func TestClientRetryAllDeadJobsBig(t *testing.T) { } func TestClientDeleteScheduledJob(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Delete an invalid job. Make sure we get error @@ -635,8 +650,10 @@ func TestClientDeleteScheduledJob(t *testing.T) { } func TestClientDeleteScheduledUniqueJob(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Schedule a unique job. Delete it. Ensure we can schedule it again. @@ -657,7 +674,7 @@ func TestClientDeleteScheduledUniqueJob(t *testing.T) { func TestClientDeleteRetryJob(t *testing.T) { pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) setNowEpochSecondsMock(1425263409) diff --git a/dead_pool_reaper_test.go b/dead_pool_reaper_test.go index 20392709..6952a536 100644 --- a/dead_pool_reaper_test.go +++ b/dead_pool_reaper_test.go @@ -5,12 +5,15 @@ import ( "time" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestDeadPoolReaper(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) conn := pool.Get() @@ -92,8 +95,10 @@ func TestDeadPoolReaper(t *testing.T) { } func TestDeadPoolReaperNoHeartbeat(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() conn := pool.Get() defer conn.Close() @@ -179,8 +184,10 @@ func TestDeadPoolReaperNoHeartbeat(t *testing.T) { } func TestDeadPoolReaperNoJobTypes(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) conn := pool.Get() @@ -256,7 +263,7 @@ func TestDeadPoolReaperNoJobTypes(t *testing.T) { func TestDeadPoolReaperWithWorkerPools(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" stalePoolID := "aaa" cleanKeyspace(ns, pool) @@ -295,8 +302,10 @@ func TestDeadPoolReaperWithWorkerPools(t *testing.T) { } func TestDeadPoolReaperCleanStaleLocks(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) conn := pool.Get() diff --git a/enqueue_test.go b/enqueue_test.go index 046455f9..1b0b3969 100644 --- a/enqueue_test.go +++ b/enqueue_test.go @@ -6,12 +6,15 @@ import ( "testing" "time" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestEnqueue(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) job, err := enqueuer.Enqueue("wat", Q{"a": 1, "b": "cool"}) @@ -53,8 +56,10 @@ func TestEnqueue(t *testing.T) { } func TestEnqueueIn(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -101,7 +106,7 @@ func TestEnqueueIn(t *testing.T) { func TestEnqueueUnique(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) var mutex = &sync.Mutex{} @@ -177,7 +182,7 @@ func TestEnqueueUnique(t *testing.T) { func TestEnqueueUniqueIn(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -233,11 +238,13 @@ func TestEnqueueUniqueIn(t *testing.T) { } func TestEnqueueUniqueByKey(t *testing.T) { + t.Parallel() + var arg3 string var arg4 string pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) var mutex = &sync.Mutex{} diff --git a/etc/out/profile.cov b/etc/out/profile.cov deleted file mode 100644 index 6003da00..00000000 --- a/etc/out/profile.cov +++ /dev/null @@ -1,731 +0,0 @@ -mode: atomic -github.com/gocraft/work/webui/webui.go:33.77,44.105 3 9 -github.com/gocraft/work/webui/webui.go:48.2,48.93 1 9 -github.com/gocraft/work/webui/webui.go:52.2,67.81 12 9 -github.com/gocraft/work/webui/webui.go:71.2,71.88 1 9 -github.com/gocraft/work/webui/webui.go:76.2,76.15 1 9 -github.com/gocraft/work/webui/webui.go:44.105,47.3 2 20 -github.com/gocraft/work/webui/webui.go:48.93,51.3 2 20 -github.com/gocraft/work/webui/webui.go:67.81,70.3 2 1 -github.com/gocraft/work/webui/webui.go:71.88,74.3 2 1 -github.com/gocraft/work/webui/webui.go:80.26,82.21 2 1 -github.com/gocraft/work/webui/webui.go:82.21,85.3 2 1 -github.com/gocraft/work/webui/webui.go:89.25,92.2 2 1 -github.com/gocraft/work/webui/webui.go:94.65,97.2 2 3 -github.com/gocraft/work/webui/webui.go:99.70,102.2 2 1 -github.com/gocraft/work/webui/webui.go:104.70,106.16 2 2 -github.com/gocraft/work/webui/webui.go:111.2,112.34 2 2 -github.com/gocraft/work/webui/webui.go:118.2,118.35 1 2 -github.com/gocraft/work/webui/webui.go:106.16,109.3 2 0 -github.com/gocraft/work/webui/webui.go:112.34,113.16 1 42 -github.com/gocraft/work/webui/webui.go:113.16,115.4 1 1 -github.com/gocraft/work/webui/webui.go:121.68,123.16 2 1 -github.com/gocraft/work/webui/webui.go:128.2,129.16 2 1 -github.com/gocraft/work/webui/webui.go:134.2,139.27 2 1 -github.com/gocraft/work/webui/webui.go:123.16,126.3 2 0 -github.com/gocraft/work/webui/webui.go:129.16,132.3 2 0 -github.com/gocraft/work/webui/webui.go:142.72,144.16 2 1 -github.com/gocraft/work/webui/webui.go:149.2,150.16 2 1 -github.com/gocraft/work/webui/webui.go:155.2,160.27 2 1 -github.com/gocraft/work/webui/webui.go:144.16,147.3 2 0 -github.com/gocraft/work/webui/webui.go:150.16,153.3 2 0 -github.com/gocraft/work/webui/webui.go:163.67,165.16 2 6 -github.com/gocraft/work/webui/webui.go:170.2,171.16 2 6 -github.com/gocraft/work/webui/webui.go:176.2,181.27 2 6 -github.com/gocraft/work/webui/webui.go:165.16,168.3 2 0 -github.com/gocraft/work/webui/webui.go:171.16,174.3 2 0 -github.com/gocraft/work/webui/webui.go:184.72,186.16 2 1 -github.com/gocraft/work/webui/webui.go:191.2,193.52 2 1 -github.com/gocraft/work/webui/webui.go:186.16,189.3 2 0 -github.com/gocraft/work/webui/webui.go:196.71,198.16 2 1 -github.com/gocraft/work/webui/webui.go:203.2,205.52 2 1 -github.com/gocraft/work/webui/webui.go:198.16,201.3 2 0 -github.com/gocraft/work/webui/webui.go:208.76,211.2 2 1 -github.com/gocraft/work/webui/webui.go:213.75,216.2 2 1 -github.com/gocraft/work/webui/webui.go:218.69,219.16 1 18 -github.com/gocraft/work/webui/webui.go:224.2,225.16 2 18 -github.com/gocraft/work/webui/webui.go:229.2,229.20 1 18 -github.com/gocraft/work/webui/webui.go:219.16,222.3 2 0 -github.com/gocraft/work/webui/webui.go:225.16,228.3 2 0 -github.com/gocraft/work/webui/webui.go:232.53,235.2 2 0 -github.com/gocraft/work/webui/webui.go:237.46,239.16 2 8 -github.com/gocraft/work/webui/webui.go:243.2,244.19 2 8 -github.com/gocraft/work/webui/webui.go:248.2,249.24 2 8 -github.com/gocraft/work/webui/webui.go:239.16,241.3 1 0 -github.com/gocraft/work/webui/webui.go:244.19,246.3 1 8 -github.com/gocraft/work/worker_pool.go:44.46,45.23 1 4 -github.com/gocraft/work/worker_pool.go:48.2,48.22 1 1 -github.com/gocraft/work/worker_pool.go:45.23,47.3 1 3 -github.com/gocraft/work/worker_pool.go:88.103,90.2 1 16 -github.com/gocraft/work/worker_pool.go:94.148,95.17 1 16 -github.com/gocraft/work/worker_pool.go:99.2,111.44 4 16 -github.com/gocraft/work/worker_pool.go:116.2,116.11 1 16 -github.com/gocraft/work/worker_pool.go:95.17,96.53 1 0 -github.com/gocraft/work/worker_pool.go:111.44,114.3 2 120 -github.com/gocraft/work/worker_pool.go:122.62,130.62 4 1 -github.com/gocraft/work/worker_pool.go:135.2,137.31 2 0 -github.com/gocraft/work/worker_pool.go:141.2,141.11 1 0 -github.com/gocraft/work/worker_pool.go:130.62,133.3 2 0 -github.com/gocraft/work/worker_pool.go:137.31,139.3 1 0 -github.com/gocraft/work/worker_pool.go:148.68,150.2 1 13 -github.com/gocraft/work/worker_pool.go:154.99,164.41 5 21 -github.com/gocraft/work/worker_pool.go:169.2,171.31 2 20 -github.com/gocraft/work/worker_pool.go:175.2,175.11 1 20 -github.com/gocraft/work/worker_pool.go:164.41,167.3 2 16 -github.com/gocraft/work/worker_pool.go:171.31,173.3 1 147 -github.com/gocraft/work/worker_pool.go:182.84,186.16 3 0 -github.com/gocraft/work/worker_pool.go:190.2,192.11 2 0 -github.com/gocraft/work/worker_pool.go:186.16,187.13 1 0 -github.com/gocraft/work/worker_pool.go:196.31,197.16 1 16 -github.com/gocraft/work/worker_pool.go:200.2,206.31 4 15 -github.com/gocraft/work/worker_pool.go:210.2,214.29 5 15 -github.com/gocraft/work/worker_pool.go:197.16,199.3 1 1 -github.com/gocraft/work/worker_pool.go:206.31,208.3 1 119 -github.com/gocraft/work/worker_pool.go:218.30,219.17 1 16 -github.com/gocraft/work/worker_pool.go:222.2,225.31 3 15 -github.com/gocraft/work/worker_pool.go:232.2,237.28 6 15 -github.com/gocraft/work/worker_pool.go:219.17,221.3 1 1 -github.com/gocraft/work/worker_pool.go:225.31,227.22 2 119 -github.com/gocraft/work/worker_pool.go:227.22,230.4 2 119 -github.com/gocraft/work/worker_pool.go:241.31,243.31 2 7 -github.com/gocraft/work/worker_pool.go:250.2,250.11 1 7 -github.com/gocraft/work/worker_pool.go:243.31,245.22 2 46 -github.com/gocraft/work/worker_pool.go:245.22,248.4 2 46 -github.com/gocraft/work/worker_pool.go:253.40,255.29 2 15 -github.com/gocraft/work/worker_pool.go:258.2,263.27 6 15 -github.com/gocraft/work/worker_pool.go:255.29,257.3 1 19 -github.com/gocraft/work/worker_pool.go:266.44,268.31 2 17 -github.com/gocraft/work/worker_pool.go:271.2,272.13 2 17 -github.com/gocraft/work/worker_pool.go:268.31,270.3 1 140 -github.com/gocraft/work/worker_pool.go:275.47,276.27 1 15 -github.com/gocraft/work/worker_pool.go:280.2,285.29 6 12 -github.com/gocraft/work/worker_pool.go:289.2,289.56 1 12 -github.com/gocraft/work/worker_pool.go:276.27,278.3 1 3 -github.com/gocraft/work/worker_pool.go:285.29,287.3 1 19 -github.com/gocraft/work/worker_pool.go:289.56,291.3 1 0 -github.com/gocraft/work/worker_pool.go:294.57,295.27 1 15 -github.com/gocraft/work/worker_pool.go:299.2,301.44 3 12 -github.com/gocraft/work/worker_pool.go:295.27,297.3 1 3 -github.com/gocraft/work/worker_pool.go:301.44,302.115 1 19 -github.com/gocraft/work/worker_pool.go:302.115,304.4 1 0 -github.com/gocraft/work/worker_pool.go:309.48,310.38 1 16 -github.com/gocraft/work/worker_pool.go:310.38,311.51 1 0 -github.com/gocraft/work/worker_pool.go:315.67,316.39 1 21 -github.com/gocraft/work/worker_pool.go:316.39,317.83 1 1 -github.com/gocraft/work/worker_pool.go:321.70,322.42 1 1 -github.com/gocraft/work/worker_pool.go:322.42,323.112 1 1 -github.com/gocraft/work/worker_pool.go:335.122,339.24 3 2 -github.com/gocraft/work/worker_pool.go:345.2,361.12 16 2 -github.com/gocraft/work/worker_pool.go:339.24,341.3 1 0 -github.com/gocraft/work/worker_pool.go:341.8,343.3 1 2 -github.com/gocraft/work/worker_pool.go:364.71,367.35 2 30 -github.com/gocraft/work/worker_pool.go:371.2,374.17 3 30 -github.com/gocraft/work/worker_pool.go:378.2,381.41 3 27 -github.com/gocraft/work/worker_pool.go:385.2,386.16 2 26 -github.com/gocraft/work/worker_pool.go:401.2,401.13 1 22 -github.com/gocraft/work/worker_pool.go:367.35,369.3 1 0 -github.com/gocraft/work/worker_pool.go:374.17,376.3 1 3 -github.com/gocraft/work/worker_pool.go:381.41,383.3 1 1 -github.com/gocraft/work/worker_pool.go:386.16,387.40 1 18 -github.com/gocraft/work/worker_pool.go:387.40,389.4 1 1 -github.com/gocraft/work/worker_pool.go:390.8,390.23 1 8 -github.com/gocraft/work/worker_pool.go:390.23,391.45 1 6 -github.com/gocraft/work/worker_pool.go:394.3,394.40 1 5 -github.com/gocraft/work/worker_pool.go:391.45,393.4 1 1 -github.com/gocraft/work/worker_pool.go:394.40,396.4 1 0 -github.com/gocraft/work/worker_pool.go:397.8,399.3 1 2 -github.com/gocraft/work/worker_pool.go:404.74,407.35 2 12 -github.com/gocraft/work/worker_pool.go:411.2,414.17 3 12 -github.com/gocraft/work/worker_pool.go:418.2,421.41 3 9 -github.com/gocraft/work/worker_pool.go:425.2,427.16 3 8 -github.com/gocraft/work/worker_pool.go:448.2,448.13 1 2 -github.com/gocraft/work/worker_pool.go:407.35,409.3 1 0 -github.com/gocraft/work/worker_pool.go:414.17,416.3 1 3 -github.com/gocraft/work/worker_pool.go:421.41,423.3 1 1 -github.com/gocraft/work/worker_pool.go:427.16,428.40 1 3 -github.com/gocraft/work/worker_pool.go:431.3,431.42 1 1 -github.com/gocraft/work/worker_pool.go:428.40,430.4 1 2 -github.com/gocraft/work/worker_pool.go:431.42,433.4 1 0 -github.com/gocraft/work/worker_pool.go:434.8,434.23 1 5 -github.com/gocraft/work/worker_pool.go:434.23,435.45 1 3 -github.com/gocraft/work/worker_pool.go:438.3,438.40 1 2 -github.com/gocraft/work/worker_pool.go:441.3,441.42 1 2 -github.com/gocraft/work/worker_pool.go:435.45,437.4 1 1 -github.com/gocraft/work/worker_pool.go:438.40,440.4 1 0 -github.com/gocraft/work/worker_pool.go:441.42,443.4 1 1 -github.com/gocraft/work/worker_pool.go:444.8,446.3 1 2 -github.com/gocraft/work/worker_pool.go:451.62,452.27 1 21 -github.com/gocraft/work/worker_pool.go:456.2,456.27 1 21 -github.com/gocraft/work/worker_pool.go:460.2,460.31 1 21 -github.com/gocraft/work/worker_pool.go:464.2,464.16 1 21 -github.com/gocraft/work/worker_pool.go:452.27,454.3 1 13 -github.com/gocraft/work/worker_pool.go:456.27,458.3 1 16 -github.com/gocraft/work/worker_pool.go:460.31,461.66 1 0 -github.com/gocraft/work/periodic_enqueuer.go:32.109,40.2 1 17 -github.com/gocraft/work/periodic_enqueuer.go:42.37,44.2 1 16 -github.com/gocraft/work/periodic_enqueuer.go:46.36,49.2 2 16 -github.com/gocraft/work/periodic_enqueuer.go:51.36,54.16 2 16 -github.com/gocraft/work/periodic_enqueuer.go:57.2,60.24 3 16 -github.com/gocraft/work/periodic_enqueuer.go:67.2,67.6 1 16 -github.com/gocraft/work/periodic_enqueuer.go:54.16,55.13 1 0 -github.com/gocraft/work/periodic_enqueuer.go:60.24,62.17 2 12 -github.com/gocraft/work/periodic_enqueuer.go:62.17,64.4 1 1 -github.com/gocraft/work/periodic_enqueuer.go:67.6,68.10 1 16 -github.com/gocraft/work/periodic_enqueuer.go:69.22,71.10 2 16 -github.com/gocraft/work/periodic_enqueuer.go:72.18,74.18 2 0 -github.com/gocraft/work/periodic_enqueuer.go:78.4,79.26 2 0 -github.com/gocraft/work/periodic_enqueuer.go:74.18,75.15 1 0 -github.com/gocraft/work/periodic_enqueuer.go:79.26,81.19 2 0 -github.com/gocraft/work/periodic_enqueuer.go:81.19,83.6 1 0 -github.com/gocraft/work/periodic_enqueuer.go:89.45,97.37 6 14 -github.com/gocraft/work/periodic_enqueuer.go:123.2,125.12 2 14 -github.com/gocraft/work/periodic_enqueuer.go:97.37,98.82 1 6 -github.com/gocraft/work/periodic_enqueuer.go:98.82,112.18 5 40 -github.com/gocraft/work/periodic_enqueuer.go:116.4,117.18 2 40 -github.com/gocraft/work/periodic_enqueuer.go:112.18,114.5 1 0 -github.com/gocraft/work/periodic_enqueuer.go:117.18,119.5 1 0 -github.com/gocraft/work/periodic_enqueuer.go:128.50,133.25 4 18 -github.com/gocraft/work/periodic_enqueuer.go:140.2,140.85 1 7 -github.com/gocraft/work/periodic_enqueuer.go:133.25,135.3 1 10 -github.com/gocraft/work/periodic_enqueuer.go:135.8,135.23 1 8 -github.com/gocraft/work/periodic_enqueuer.go:135.23,138.3 2 1 -github.com/gocraft/work/periodic_enqueuer.go:143.66,145.2 1 40 -github.com/gocraft/work/requeuer.go:24.102,28.35 4 32 -github.com/gocraft/work/requeuer.go:31.2,46.3 3 32 -github.com/gocraft/work/requeuer.go:28.35,30.3 1 42 -github.com/gocraft/work/requeuer.go:49.28,51.2 1 32 -github.com/gocraft/work/requeuer.go:53.27,56.2 2 32 -github.com/gocraft/work/requeuer.go:58.28,61.2 2 2 -github.com/gocraft/work/requeuer.go:63.27,70.6 2 32 -github.com/gocraft/work/requeuer.go:70.6,71.10 1 48 -github.com/gocraft/work/requeuer.go:72.21,74.10 2 32 -github.com/gocraft/work/requeuer.go:75.22,76.20 1 2 -github.com/gocraft/work/requeuer.go:78.4,78.36 1 2 -github.com/gocraft/work/requeuer.go:79.17,80.20 1 14 -github.com/gocraft/work/requeuer.go:76.21,77.5 0 4 -github.com/gocraft/work/requeuer.go:80.21,81.5 0 0 -github.com/gocraft/work/requeuer.go:86.35,93.25 5 20 -github.com/gocraft/work/requeuer.go:100.2,100.15 1 4 -github.com/gocraft/work/requeuer.go:109.2,109.14 1 0 -github.com/gocraft/work/requeuer.go:93.25,95.3 1 12 -github.com/gocraft/work/requeuer.go:95.8,95.23 1 8 -github.com/gocraft/work/requeuer.go:95.23,98.3 2 4 -github.com/gocraft/work/requeuer.go:100.15,102.3 1 0 -github.com/gocraft/work/requeuer.go:102.8,102.26 1 4 -github.com/gocraft/work/requeuer.go:102.26,105.3 2 1 -github.com/gocraft/work/requeuer.go:105.8,105.24 1 3 -github.com/gocraft/work/requeuer.go:105.24,107.3 1 3 -github.com/gocraft/work/time.go:7.30,8.18 1 292 -github.com/gocraft/work/time.go:11.2,11.26 1 232 -github.com/gocraft/work/time.go:8.18,10.3 1 60 -github.com/gocraft/work/time.go:14.38,16.2 1 25 -github.com/gocraft/work/time.go:18.33,20.2 1 15 -github.com/gocraft/work/redis.go:9.52,11.40 2 2543 -github.com/gocraft/work/redis.go:14.2,14.18 1 2543 -github.com/gocraft/work/redis.go:11.40,13.3 1 2543 -github.com/gocraft/work/redis.go:17.49,19.2 1 77 -github.com/gocraft/work/redis.go:23.50,25.2 1 1818 -github.com/gocraft/work/redis.go:27.53,29.2 1 1746 -github.com/gocraft/work/redis.go:31.71,33.2 1 273 -github.com/gocraft/work/redis.go:35.45,37.2 1 37 -github.com/gocraft/work/redis.go:39.44,41.2 1 101 -github.com/gocraft/work/redis.go:43.49,45.2 1 89 -github.com/gocraft/work/redis.go:47.67,49.2 1 239 -github.com/gocraft/work/redis.go:51.51,53.2 1 58 -github.com/gocraft/work/redis.go:55.63,57.2 1 65 -github.com/gocraft/work/redis.go:59.59,61.2 1 234 -github.com/gocraft/work/redis.go:63.57,65.2 1 312 -github.com/gocraft/work/redis.go:67.61,69.2 1 316 -github.com/gocraft/work/redis.go:71.64,73.2 1 242 -github.com/gocraft/work/redis.go:75.96,83.17 6 25 -github.com/gocraft/work/redis.go:90.2,90.26 1 25 -github.com/gocraft/work/redis.go:83.17,85.17 2 15 -github.com/gocraft/work/redis.go:85.17,87.4 1 0 -github.com/gocraft/work/redis.go:93.59,95.2 1 34 -github.com/gocraft/work/dead_pool_reaper.go:31.98,41.2 1 20 -github.com/gocraft/work/dead_pool_reaper.go:43.34,45.2 1 16 -github.com/gocraft/work/dead_pool_reaper.go:47.33,50.2 2 16 -github.com/gocraft/work/dead_pool_reaper.go:52.33,57.6 3 16 -github.com/gocraft/work/dead_pool_reaper.go:57.6,58.10 1 17 -github.com/gocraft/work/dead_pool_reaper.go:59.21,61.10 2 16 -github.com/gocraft/work/dead_pool_reaper.go:62.18,64.18 2 1 -github.com/gocraft/work/dead_pool_reaper.go:69.4,72.35 2 1 -github.com/gocraft/work/dead_pool_reaper.go:64.18,65.15 1 0 -github.com/gocraft/work/dead_pool_reaper.go:72.35,74.5 1 0 -github.com/gocraft/work/dead_pool_reaper.go:79.39,82.16 2 4 -github.com/gocraft/work/dead_pool_reaper.go:86.2,92.48 4 4 -github.com/gocraft/work/dead_pool_reaper.go:114.2,114.12 1 4 -github.com/gocraft/work/dead_pool_reaper.go:82.16,84.3 1 0 -github.com/gocraft/work/dead_pool_reaper.go:92.48,95.24 2 7 -github.com/gocraft/work/dead_pool_reaper.go:105.3,105.71 1 7 -github.com/gocraft/work/dead_pool_reaper.go:109.3,109.71 1 7 -github.com/gocraft/work/dead_pool_reaper.go:95.24,97.87 2 4 -github.com/gocraft/work/dead_pool_reaper.go:97.87,99.5 1 0 -github.com/gocraft/work/dead_pool_reaper.go:100.9,103.4 1 3 -github.com/gocraft/work/dead_pool_reaper.go:105.71,107.4 1 0 -github.com/gocraft/work/dead_pool_reaper.go:109.71,111.4 1 0 -github.com/gocraft/work/dead_pool_reaper.go:117.85,122.35 4 9 -github.com/gocraft/work/dead_pool_reaper.go:125.2,129.72 4 9 -github.com/gocraft/work/dead_pool_reaper.go:133.2,133.12 1 9 -github.com/gocraft/work/dead_pool_reaper.go:122.35,124.3 1 14 -github.com/gocraft/work/dead_pool_reaper.go:129.72,131.3 1 0 -github.com/gocraft/work/dead_pool_reaper.go:136.88,141.35 4 4 -github.com/gocraft/work/dead_pool_reaper.go:145.2,151.6 4 4 -github.com/gocraft/work/dead_pool_reaper.go:141.35,144.3 1 7 -github.com/gocraft/work/dead_pool_reaper.go:151.6,153.26 2 7 -github.com/gocraft/work/dead_pool_reaper.go:159.3,159.23 1 3 -github.com/gocraft/work/dead_pool_reaper.go:153.26,155.4 1 4 -github.com/gocraft/work/dead_pool_reaper.go:155.9,155.24 1 3 -github.com/gocraft/work/dead_pool_reaper.go:155.24,157.4 1 0 -github.com/gocraft/work/dead_pool_reaper.go:159.23,161.4 1 0 -github.com/gocraft/work/dead_pool_reaper.go:165.71,172.16 5 7 -github.com/gocraft/work/dead_pool_reaper.go:176.2,177.45 2 7 -github.com/gocraft/work/dead_pool_reaper.go:205.2,205.23 1 7 -github.com/gocraft/work/dead_pool_reaper.go:172.16,174.3 1 0 -github.com/gocraft/work/dead_pool_reaper.go:177.45,180.26 3 17 -github.com/gocraft/work/dead_pool_reaper.go:185.3,185.17 1 11 -github.com/gocraft/work/dead_pool_reaper.go:190.3,190.66 1 11 -github.com/gocraft/work/dead_pool_reaper.go:194.3,195.26 2 9 -github.com/gocraft/work/dead_pool_reaper.go:198.3,198.17 1 7 -github.com/gocraft/work/dead_pool_reaper.go:202.3,202.61 1 7 -github.com/gocraft/work/dead_pool_reaper.go:180.26,183.12 2 6 -github.com/gocraft/work/dead_pool_reaper.go:185.17,187.4 1 0 -github.com/gocraft/work/dead_pool_reaper.go:190.66,191.12 1 2 -github.com/gocraft/work/dead_pool_reaper.go:195.26,196.12 1 2 -github.com/gocraft/work/dead_pool_reaper.go:198.17,200.4 1 0 -github.com/gocraft/work/job.go:36.70,39.16 3 171 -github.com/gocraft/work/job.go:42.2,45.18 4 171 -github.com/gocraft/work/job.go:39.16,41.3 1 0 -github.com/gocraft/work/job.go:48.43,50.2 1 10166 -github.com/gocraft/work/job.go:53.51,54.19 1 36 -github.com/gocraft/work/job.go:57.2,57.19 1 36 -github.com/gocraft/work/job.go:54.19,56.3 1 5 -github.com/gocraft/work/job.go:60.33,64.2 3 9 -github.com/gocraft/work/job.go:67.35,68.23 1 1 -github.com/gocraft/work/job.go:68.23,70.3 1 1 -github.com/gocraft/work/job.go:76.44,78.8 2 16 -github.com/gocraft/work/job.go:87.2,87.11 1 4 -github.com/gocraft/work/job.go:78.8,80.9 2 14 -github.com/gocraft/work/job.go:83.3,83.47 1 2 -github.com/gocraft/work/job.go:80.9,82.4 1 12 -github.com/gocraft/work/job.go:84.8,86.3 1 2 -github.com/gocraft/work/job.go:93.42,95.8 2 37 -github.com/gocraft/work/job.go:115.2,115.10 1 7 -github.com/gocraft/work/job.go:95.8,97.22 2 36 -github.com/gocraft/work/job.go:111.3,111.46 1 6 -github.com/gocraft/work/job.go:97.22,99.4 1 12 -github.com/gocraft/work/job.go:99.9,99.30 1 24 -github.com/gocraft/work/job.go:99.30,101.30 2 3 -github.com/gocraft/work/job.go:101.30,103.5 1 2 -github.com/gocraft/work/job.go:104.9,104.31 1 21 -github.com/gocraft/work/job.go:104.31,107.101 3 19 -github.com/gocraft/work/job.go:107.101,109.5 1 16 -github.com/gocraft/work/job.go:112.8,114.3 1 1 -github.com/gocraft/work/job.go:121.46,123.8 2 12 -github.com/gocraft/work/job.go:136.2,136.12 1 3 -github.com/gocraft/work/job.go:123.8,125.22 2 11 -github.com/gocraft/work/job.go:132.3,132.48 1 2 -github.com/gocraft/work/job.go:125.22,127.4 1 4 -github.com/gocraft/work/job.go:127.9,127.30 1 7 -github.com/gocraft/work/job.go:127.30,129.4 1 0 -github.com/gocraft/work/job.go:129.9,129.31 1 7 -github.com/gocraft/work/job.go:129.31,131.4 1 5 -github.com/gocraft/work/job.go:133.8,135.3 1 1 -github.com/gocraft/work/job.go:142.40,144.8 2 7 -github.com/gocraft/work/job.go:153.2,153.14 1 3 -github.com/gocraft/work/job.go:144.8,146.9 2 6 -github.com/gocraft/work/job.go:149.3,149.45 1 2 -github.com/gocraft/work/job.go:146.9,148.4 1 4 -github.com/gocraft/work/job.go:150.8,152.3 1 1 -github.com/gocraft/work/job.go:157.32,159.2 1 54 -github.com/gocraft/work/job.go:161.38,164.2 2 47 -github.com/gocraft/work/job.go:166.39,169.2 2 31 -github.com/gocraft/work/job.go:171.40,174.2 2 28 -github.com/gocraft/work/job.go:176.50,178.2 1 5 -github.com/gocraft/work/job.go:180.63,183.2 2 12 -github.com/gocraft/work/priority_sampler.go:26.157,38.2 3 226 -github.com/gocraft/work/priority_sampler.go:47.49,59.20 5 471 -github.com/gocraft/work/priority_sampler.go:85.2,85.18 1 471 -github.com/gocraft/work/priority_sampler.go:59.20,61.17 2 532 -github.com/gocraft/work/priority_sampler.go:66.3,68.51 3 532 -github.com/gocraft/work/priority_sampler.go:81.3,82.14 2 532 -github.com/gocraft/work/priority_sampler.go:61.17,62.14 1 0 -github.com/gocraft/work/priority_sampler.go:68.51,70.40 2 1014 -github.com/gocraft/work/priority_sampler.go:70.40,75.10 3 532 -github.com/gocraft/work/priority_sampler.go:76.10,78.5 1 482 -github.com/gocraft/work/run.go:10.136,16.22 5 50 -github.com/gocraft/work/run.go:41.2,41.15 1 50 -github.com/gocraft/work/run.go:51.2,51.26 1 50 -github.com/gocraft/work/run.go:16.22,17.40 1 55 -github.com/gocraft/work/run.go:30.3,30.19 1 48 -github.com/gocraft/work/run.go:33.3,35.15 3 24 -github.com/gocraft/work/run.go:38.3,38.19 1 1 -github.com/gocraft/work/run.go:17.40,20.20 3 7 -github.com/gocraft/work/run.go:23.4,25.16 3 2 -github.com/gocraft/work/run.go:28.4,28.20 1 0 -github.com/gocraft/work/run.go:20.20,22.5 1 5 -github.com/gocraft/work/run.go:25.16,27.5 1 2 -github.com/gocraft/work/run.go:30.19,32.4 1 24 -github.com/gocraft/work/run.go:35.15,37.4 1 22 -github.com/gocraft/work/run.go:41.15,42.45 1 50 -github.com/gocraft/work/run.go:42.45,48.4 3 2 -github.com/gocraft/work/worker.go:36.154,40.29 3 126 -github.com/gocraft/work/worker.go:44.2,63.10 3 126 -github.com/gocraft/work/worker.go:40.29,42.3 1 126 -github.com/gocraft/work/worker.go:67.109,70.30 3 273 -github.com/gocraft/work/worker.go:79.2,81.91 3 273 -github.com/gocraft/work/worker.go:70.30,78.3 1 223 -github.com/gocraft/work/worker.go:84.26,87.2 2 125 -github.com/gocraft/work/worker.go:89.25,94.2 4 125 -github.com/gocraft/work/worker.go:96.26,100.2 3 52 -github.com/gocraft/work/worker.go:104.25,112.6 5 125 -github.com/gocraft/work/worker.go:112.6,113.10 1 448 -github.com/gocraft/work/worker.go:114.21,116.10 2 125 -github.com/gocraft/work/worker.go:117.22,119.18 2 52 -github.com/gocraft/work/worker.go:120.18,122.18 2 271 -github.com/gocraft/work/worker.go:122.18,125.5 2 10 -github.com/gocraft/work/worker.go:125.10,125.25 1 261 -github.com/gocraft/work/worker.go:125.25,129.5 3 45 -github.com/gocraft/work/worker.go:129.10,130.16 1 216 -github.com/gocraft/work/worker.go:134.5,136.43 3 216 -github.com/gocraft/work/worker.go:139.5,139.72 1 216 -github.com/gocraft/work/worker.go:130.16,133.6 2 52 -github.com/gocraft/work/worker.go:136.43,138.6 1 3 -github.com/gocraft/work/worker.go:145.43,152.38 4 271 -github.com/gocraft/work/worker.go:155.2,160.25 5 271 -github.com/gocraft/work/worker.go:166.2,166.22 1 45 -github.com/gocraft/work/worker.go:170.2,171.9 2 45 -github.com/gocraft/work/worker.go:175.2,176.9 2 45 -github.com/gocraft/work/worker.go:180.2,181.9 2 45 -github.com/gocraft/work/worker.go:185.2,186.16 2 45 -github.com/gocraft/work/worker.go:190.2,190.17 1 45 -github.com/gocraft/work/worker.go:152.38,154.3 1 373 -github.com/gocraft/work/worker.go:160.25,162.3 1 216 -github.com/gocraft/work/worker.go:162.8,162.23 1 55 -github.com/gocraft/work/worker.go:162.23,164.3 1 10 -github.com/gocraft/work/worker.go:166.22,168.3 1 0 -github.com/gocraft/work/worker.go:171.9,173.3 1 0 -github.com/gocraft/work/worker.go:176.9,178.3 1 0 -github.com/gocraft/work/worker.go:181.9,183.3 1 0 -github.com/gocraft/work/worker.go:186.16,188.3 1 0 -github.com/gocraft/work/worker.go:193.39,194.16 1 45 -github.com/gocraft/work/worker.go:203.2,205.15 3 45 -github.com/gocraft/work/worker.go:215.2,216.19 2 45 -github.com/gocraft/work/worker.go:220.2,220.38 1 45 -github.com/gocraft/work/worker.go:194.16,199.24 2 7 -github.com/gocraft/work/worker.go:199.24,201.4 1 3 -github.com/gocraft/work/worker.go:205.15,208.3 2 0 -github.com/gocraft/work/worker.go:208.8,213.3 4 45 -github.com/gocraft/work/worker.go:216.19,219.3 2 9 -github.com/gocraft/work/worker.go:223.55,227.25 3 7 -github.com/gocraft/work/worker.go:237.2,241.16 4 7 -github.com/gocraft/work/worker.go:246.2,247.16 2 7 -github.com/gocraft/work/worker.go:254.2,254.28 1 7 -github.com/gocraft/work/worker.go:259.2,260.16 2 3 -github.com/gocraft/work/worker.go:265.2,265.20 1 3 -github.com/gocraft/work/worker.go:227.25,229.3 1 7 -github.com/gocraft/work/worker.go:229.8,231.17 2 0 -github.com/gocraft/work/worker.go:231.17,234.4 2 0 -github.com/gocraft/work/worker.go:241.16,244.3 2 0 -github.com/gocraft/work/worker.go:247.16,250.3 2 0 -github.com/gocraft/work/worker.go:254.28,256.3 1 4 -github.com/gocraft/work/worker.go:260.16,263.3 2 0 -github.com/gocraft/work/worker.go:268.70,277.43 8 45 -github.com/gocraft/work/worker.go:277.43,279.3 1 0 -github.com/gocraft/work/worker.go:284.35,284.36 0 37 -github.com/gocraft/work/worker.go:285.70,287.16 2 4 -github.com/gocraft/work/worker.go:291.2,291.31 1 4 -github.com/gocraft/work/worker.go:287.16,290.3 2 0 -github.com/gocraft/work/worker.go:291.31,293.3 1 4 -github.com/gocraft/work/worker.go:295.56,297.16 2 4 -github.com/gocraft/work/worker.go:301.2,301.31 1 4 -github.com/gocraft/work/worker.go:297.16,300.3 2 0 -github.com/gocraft/work/worker.go:301.31,308.3 1 4 -github.com/gocraft/work/worker.go:311.61,312.15 1 9 -github.com/gocraft/work/worker.go:321.2,321.33 1 4 -github.com/gocraft/work/worker.go:312.15,314.25 2 9 -github.com/gocraft/work/worker.go:317.3,317.18 1 5 -github.com/gocraft/work/worker.go:314.25,316.4 1 4 -github.com/gocraft/work/worker.go:317.18,319.4 1 1 -github.com/gocraft/work/worker.go:325.47,328.16 3 3 -github.com/gocraft/work/worker.go:332.2,332.73 1 3 -github.com/gocraft/work/worker.go:328.16,329.13 1 0 -github.com/gocraft/work/heartbeater.go:32.179,44.26 3 17 -github.com/gocraft/work/heartbeater.go:47.2,55.16 7 17 -github.com/gocraft/work/heartbeater.go:59.2,61.10 2 17 -github.com/gocraft/work/heartbeater.go:44.26,46.3 1 22 -github.com/gocraft/work/heartbeater.go:55.16,58.3 2 0 -github.com/gocraft/work/heartbeater.go:64.41,66.2 1 17 -github.com/gocraft/work/heartbeater.go:68.40,71.2 2 17 -github.com/gocraft/work/heartbeater.go:73.40,77.6 4 17 -github.com/gocraft/work/heartbeater.go:77.6,78.10 1 18 -github.com/gocraft/work/heartbeater.go:79.21,82.10 3 17 -github.com/gocraft/work/heartbeater.go:83.17,84.17 1 1 -github.com/gocraft/work/heartbeater.go:89.45,107.37 7 18 -github.com/gocraft/work/heartbeater.go:107.37,109.3 1 1 -github.com/gocraft/work/heartbeater.go:112.51,122.37 7 17 -github.com/gocraft/work/heartbeater.go:122.37,124.3 1 1 -github.com/gocraft/work/identifier.go:9.30,12.16 3 10261 -github.com/gocraft/work/identifier.go:15.2,15.29 1 10261 -github.com/gocraft/work/identifier.go:12.16,14.3 1 0 -github.com/gocraft/work/observer.go:65.81,78.2 1 130 -github.com/gocraft/work/observer.go:80.28,82.2 1 129 -github.com/gocraft/work/observer.go:84.27,87.2 2 129 -github.com/gocraft/work/observer.go:89.28,92.2 2 183 -github.com/gocraft/work/observer.go:94.92,102.2 1 49 -github.com/gocraft/work/observer.go:104.66,111.2 1 46 -github.com/gocraft/work/observer.go:113.67,121.2 1 2 -github.com/gocraft/work/observer.go:123.27,129.6 2 129 -github.com/gocraft/work/observer.go:129.6,130.10 1 430 -github.com/gocraft/work/observer.go:131.21,133.10 2 129 -github.com/gocraft/work/observer.go:134.22,136.8 1 183 -github.com/gocraft/work/observer.go:148.17,149.41 1 27 -github.com/gocraft/work/observer.go:155.36,156.18 1 91 -github.com/gocraft/work/observer.go:136.8,137.12 1 189 -github.com/gocraft/work/observer.go:138.38,139.20 1 6 -github.com/gocraft/work/observer.go:140.13,141.71 1 183 -github.com/gocraft/work/observer.go:144.6,145.22 2 183 -github.com/gocraft/work/observer.go:141.71,143.7 1 10 -github.com/gocraft/work/observer.go:149.41,150.70 1 8 -github.com/gocraft/work/observer.go:153.5,153.37 1 8 -github.com/gocraft/work/observer.go:150.70,152.6 1 0 -github.com/gocraft/work/observer.go:161.46,162.40 1 97 -github.com/gocraft/work/observer.go:174.2,177.20 2 97 -github.com/gocraft/work/observer.go:162.40,164.3 1 49 -github.com/gocraft/work/observer.go:164.8,164.44 1 48 -github.com/gocraft/work/observer.go:164.44,166.3 1 46 -github.com/gocraft/work/observer.go:166.8,166.47 1 2 -github.com/gocraft/work/observer.go:166.47,167.95 1 2 -github.com/gocraft/work/observer.go:167.95,170.4 2 2 -github.com/gocraft/work/observer.go:170.9,172.4 1 0 -github.com/gocraft/work/observer.go:177.20,178.68 1 29 -github.com/gocraft/work/observer.go:181.3,181.35 1 29 -github.com/gocraft/work/observer.go:178.68,180.4 1 0 -github.com/gocraft/work/observer.go:185.56,191.16 4 220 -github.com/gocraft/work/observer.go:239.2,239.12 1 210 -github.com/gocraft/work/observer.go:191.16,192.48 1 178 -github.com/gocraft/work/observer.go:192.48,194.4 1 10 -github.com/gocraft/work/observer.go:195.8,205.30 2 42 -github.com/gocraft/work/observer.go:215.3,224.49 3 42 -github.com/gocraft/work/observer.go:231.3,233.38 3 42 -github.com/gocraft/work/observer.go:205.30,207.4 1 16 -github.com/gocraft/work/observer.go:207.9,210.18 3 26 -github.com/gocraft/work/observer.go:210.18,212.5 1 0 -github.com/gocraft/work/observer.go:224.49,229.4 1 2 -github.com/gocraft/work/observer.go:233.38,235.4 1 0 -github.com/gocraft/work/client.go:27.60,32.2 1 16 -github.com/gocraft/work/client.go:47.73,54.16 5 4 -github.com/gocraft/work/client.go:57.2,59.37 2 4 -github.com/gocraft/work/client.go:64.2,64.37 1 4 -github.com/gocraft/work/client.go:69.2,71.37 2 4 -github.com/gocraft/work/client.go:117.2,117.24 1 4 -github.com/gocraft/work/client.go:54.16,56.3 1 0 -github.com/gocraft/work/client.go:59.37,62.3 2 3 -github.com/gocraft/work/client.go:64.37,67.3 2 0 -github.com/gocraft/work/client.go:71.37,73.17 2 3 -github.com/gocraft/work/client.go:78.3,82.39 2 3 -github.com/gocraft/work/client.go:114.3,114.45 1 3 -github.com/gocraft/work/client.go:73.17,76.4 2 0 -github.com/gocraft/work/client.go:82.39,87.29 4 21 -github.com/gocraft/work/client.go:108.4,108.18 1 21 -github.com/gocraft/work/client.go:87.29,89.5 1 3 -github.com/gocraft/work/client.go:89.10,89.34 1 18 -github.com/gocraft/work/client.go:89.34,91.5 1 3 -github.com/gocraft/work/client.go:91.10,91.33 1 15 -github.com/gocraft/work/client.go:91.33,94.5 2 3 -github.com/gocraft/work/client.go:94.10,94.35 1 12 -github.com/gocraft/work/client.go:94.35,98.5 3 3 -github.com/gocraft/work/client.go:98.10,98.28 1 9 -github.com/gocraft/work/client.go:98.28,100.5 1 3 -github.com/gocraft/work/client.go:100.10,100.27 1 6 -github.com/gocraft/work/client.go:100.27,104.5 3 3 -github.com/gocraft/work/client.go:104.10,104.34 1 3 -github.com/gocraft/work/client.go:104.34,107.5 2 3 -github.com/gocraft/work/client.go:108.18,111.5 2 0 -github.com/gocraft/work/client.go:135.69,140.16 4 2 -github.com/gocraft/work/client.go:145.2,146.25 2 2 -github.com/gocraft/work/client.go:150.2,150.32 1 2 -github.com/gocraft/work/client.go:155.2,155.37 1 2 -github.com/gocraft/work/client.go:160.2,162.32 2 2 -github.com/gocraft/work/client.go:202.2,202.26 1 2 -github.com/gocraft/work/client.go:140.16,143.3 2 0 -github.com/gocraft/work/client.go:146.25,148.3 1 1 -github.com/gocraft/work/client.go:150.32,153.3 2 10 -github.com/gocraft/work/client.go:155.37,158.3 2 0 -github.com/gocraft/work/client.go:162.32,164.17 2 10 -github.com/gocraft/work/client.go:169.3,173.39 2 10 -github.com/gocraft/work/client.go:199.3,199.42 1 10 -github.com/gocraft/work/client.go:164.17,167.4 2 0 -github.com/gocraft/work/client.go:173.39,180.25 5 8 -github.com/gocraft/work/client.go:193.4,193.18 1 8 -github.com/gocraft/work/client.go:180.25,182.5 1 2 -github.com/gocraft/work/client.go:182.10,182.30 1 6 -github.com/gocraft/work/client.go:182.30,184.5 1 2 -github.com/gocraft/work/client.go:184.10,184.34 1 4 -github.com/gocraft/work/client.go:184.34,186.5 1 2 -github.com/gocraft/work/client.go:186.10,186.28 1 2 -github.com/gocraft/work/client.go:186.28,188.5 1 2 -github.com/gocraft/work/client.go:188.10,188.31 1 0 -github.com/gocraft/work/client.go:188.31,190.5 1 0 -github.com/gocraft/work/client.go:190.10,190.34 1 0 -github.com/gocraft/work/client.go:190.34,192.5 1 0 -github.com/gocraft/work/client.go:193.18,196.5 2 0 -github.com/gocraft/work/client.go:213.45,219.16 5 8 -github.com/gocraft/work/client.go:222.2,224.35 2 8 -github.com/gocraft/work/client.go:228.2,228.37 1 8 -github.com/gocraft/work/client.go:233.2,235.35 2 8 -github.com/gocraft/work/client.go:250.2,250.27 1 8 -github.com/gocraft/work/client.go:256.2,256.37 1 8 -github.com/gocraft/work/client.go:261.2,263.27 2 8 -github.com/gocraft/work/client.go:279.2,279.20 1 8 -github.com/gocraft/work/client.go:219.16,221.3 1 0 -github.com/gocraft/work/client.go:224.35,226.3 1 25 -github.com/gocraft/work/client.go:228.37,231.3 2 0 -github.com/gocraft/work/client.go:235.35,237.17 2 25 -github.com/gocraft/work/client.go:242.3,247.33 2 25 -github.com/gocraft/work/client.go:237.17,240.4 2 0 -github.com/gocraft/work/client.go:250.27,251.18 1 25 -github.com/gocraft/work/client.go:251.18,253.4 1 8 -github.com/gocraft/work/client.go:256.37,259.3 2 0 -github.com/gocraft/work/client.go:263.27,264.18 1 25 -github.com/gocraft/work/client.go:264.18,266.18 2 8 -github.com/gocraft/work/client.go:271.4,272.18 2 8 -github.com/gocraft/work/client.go:275.4,275.36 1 8 -github.com/gocraft/work/client.go:266.18,269.5 2 0 -github.com/gocraft/work/client.go:272.18,274.5 1 0 -github.com/gocraft/work/client.go:301.75,304.16 3 3 -github.com/gocraft/work/client.go:309.2,311.37 2 3 -github.com/gocraft/work/client.go:315.2,315.25 1 3 -github.com/gocraft/work/client.go:304.16,307.3 2 0 -github.com/gocraft/work/client.go:311.37,313.3 1 43 -github.com/gocraft/work/client.go:319.67,322.16 3 2 -github.com/gocraft/work/client.go:327.2,329.37 2 2 -github.com/gocraft/work/client.go:333.2,333.25 1 2 -github.com/gocraft/work/client.go:322.16,325.3 2 0 -github.com/gocraft/work/client.go:329.37,331.3 1 2 -github.com/gocraft/work/client.go:337.65,340.16 3 19 -github.com/gocraft/work/client.go:345.2,347.37 2 19 -github.com/gocraft/work/client.go:351.2,351.25 1 19 -github.com/gocraft/work/client.go:340.16,343.3 2 0 -github.com/gocraft/work/client.go:347.37,349.3 1 50 -github.com/gocraft/work/client.go:355.66,357.16 2 5 -github.com/gocraft/work/client.go:360.2,360.9 1 5 -github.com/gocraft/work/client.go:363.2,363.12 1 5 -github.com/gocraft/work/client.go:357.16,359.3 1 0 -github.com/gocraft/work/client.go:360.9,362.3 1 0 -github.com/gocraft/work/client.go:367.65,370.16 2 5 -github.com/gocraft/work/client.go:376.2,377.27 2 5 -github.com/gocraft/work/client.go:381.2,385.35 4 5 -github.com/gocraft/work/client.go:388.2,397.16 8 5 -github.com/gocraft/work/client.go:402.2,402.14 1 5 -github.com/gocraft/work/client.go:406.2,406.12 1 5 -github.com/gocraft/work/client.go:370.16,373.3 2 0 -github.com/gocraft/work/client.go:377.27,379.3 1 17 -github.com/gocraft/work/client.go:385.35,387.3 1 17 -github.com/gocraft/work/client.go:397.16,400.3 2 0 -github.com/gocraft/work/client.go:402.14,404.3 1 0 -github.com/gocraft/work/client.go:410.43,413.16 2 2 -github.com/gocraft/work/client.go:419.2,420.27 2 2 -github.com/gocraft/work/client.go:424.2,428.35 4 2 -github.com/gocraft/work/client.go:431.2,440.28 6 2 -github.com/gocraft/work/client.go:452.2,452.12 1 2 -github.com/gocraft/work/client.go:413.16,416.3 2 0 -github.com/gocraft/work/client.go:420.27,422.3 1 5 -github.com/gocraft/work/client.go:428.35,430.3 1 5 -github.com/gocraft/work/client.go:440.28,442.17 2 14 -github.com/gocraft/work/client.go:447.3,447.15 1 14 -github.com/gocraft/work/client.go:442.17,445.4 2 0 -github.com/gocraft/work/client.go:447.15,448.9 1 2 -github.com/gocraft/work/client.go:456.44,460.16 4 1 -github.com/gocraft/work/client.go:465.2,465.12 1 1 -github.com/gocraft/work/client.go:460.16,463.3 2 0 -github.com/gocraft/work/client.go:469.77,471.16 2 3 -github.com/gocraft/work/client.go:476.2,476.23 1 3 -github.com/gocraft/work/client.go:500.2,500.9 1 3 -github.com/gocraft/work/client.go:503.2,503.12 1 2 -github.com/gocraft/work/client.go:471.16,473.3 1 0 -github.com/gocraft/work/client.go:476.23,478.17 2 2 -github.com/gocraft/work/client.go:483.3,483.17 1 2 -github.com/gocraft/work/client.go:478.17,481.4 2 0 -github.com/gocraft/work/client.go:483.17,485.18 2 1 -github.com/gocraft/work/client.go:489.4,493.18 4 1 -github.com/gocraft/work/client.go:485.18,488.5 2 0 -github.com/gocraft/work/client.go:493.18,496.5 2 0 -github.com/gocraft/work/client.go:500.9,502.3 1 1 -github.com/gocraft/work/client.go:507.68,509.16 2 1 -github.com/gocraft/work/client.go:512.2,512.9 1 1 -github.com/gocraft/work/client.go:515.2,515.12 1 1 -github.com/gocraft/work/client.go:509.16,511.3 1 0 -github.com/gocraft/work/client.go:512.9,514.3 1 0 -github.com/gocraft/work/client.go:519.98,530.22 9 9 -github.com/gocraft/work/client.go:534.2,536.16 3 9 -github.com/gocraft/work/client.go:541.2,541.31 1 9 -github.com/gocraft/work/client.go:530.22,532.3 1 0 -github.com/gocraft/work/client.go:536.16,539.3 2 0 -github.com/gocraft/work/client.go:550.80,554.15 3 24 -github.com/gocraft/work/client.go:558.2,559.16 2 24 -github.com/gocraft/work/client.go:564.2,566.65 2 24 -github.com/gocraft/work/client.go:571.2,571.37 1 24 -github.com/gocraft/work/client.go:581.2,582.16 2 24 -github.com/gocraft/work/client.go:587.2,587.35 1 24 -github.com/gocraft/work/client.go:554.15,556.3 1 0 -github.com/gocraft/work/client.go:559.16,562.3 2 0 -github.com/gocraft/work/client.go:566.65,569.3 2 0 -github.com/gocraft/work/client.go:571.37,573.17 2 95 -github.com/gocraft/work/client.go:578.3,578.30 1 95 -github.com/gocraft/work/client.go:573.17,576.4 2 0 -github.com/gocraft/work/client.go:582.16,585.3 2 0 -github.com/gocraft/work/enqueue.go:23.64,24.17 1 24 -github.com/gocraft/work/enqueue.go:28.2,35.3 1 24 -github.com/gocraft/work/enqueue.go:24.17,25.51 1 0 -github.com/gocraft/work/enqueue.go:40.87,49.16 3 65 -github.com/gocraft/work/enqueue.go:53.2,56.76 3 65 -github.com/gocraft/work/enqueue.go:60.2,60.56 1 65 -github.com/gocraft/work/enqueue.go:64.2,64.17 1 65 -github.com/gocraft/work/enqueue.go:49.16,51.3 1 0 -github.com/gocraft/work/enqueue.go:56.76,58.3 1 0 -github.com/gocraft/work/enqueue.go:60.56,62.3 1 0 -github.com/gocraft/work/enqueue.go:68.120,77.16 3 11 -github.com/gocraft/work/enqueue.go:81.2,90.16 5 11 -github.com/gocraft/work/enqueue.go:94.2,94.56 1 11 -github.com/gocraft/work/enqueue.go:98.2,98.26 1 11 -github.com/gocraft/work/enqueue.go:77.16,79.3 1 0 -github.com/gocraft/work/enqueue.go:90.16,92.3 1 0 -github.com/gocraft/work/enqueue.go:94.56,96.3 1 0 -github.com/gocraft/work/enqueue.go:107.93,109.2 1 9 -github.com/gocraft/work/enqueue.go:112.126,114.2 1 8 -github.com/gocraft/work/enqueue.go:122.129,124.16 2 16 -github.com/gocraft/work/enqueue.go:128.2,130.31 2 16 -github.com/gocraft/work/enqueue.go:133.2,133.17 1 3 -github.com/gocraft/work/enqueue.go:124.16,126.3 1 0 -github.com/gocraft/work/enqueue.go:130.31,132.3 1 13 -github.com/gocraft/work/enqueue.go:138.162,140.16 2 8 -github.com/gocraft/work/enqueue.go:144.2,150.31 3 8 -github.com/gocraft/work/enqueue.go:153.2,153.17 1 2 -github.com/gocraft/work/enqueue.go:140.16,142.3 1 0 -github.com/gocraft/work/enqueue.go:150.31,152.3 1 6 -github.com/gocraft/work/enqueue.go:156.74,164.8 6 100 -github.com/gocraft/work/enqueue.go:169.2,169.14 1 100 -github.com/gocraft/work/enqueue.go:179.2,179.12 1 100 -github.com/gocraft/work/enqueue.go:164.8,165.14 1 64 -github.com/gocraft/work/enqueue.go:165.14,167.4 1 63 -github.com/gocraft/work/enqueue.go:169.14,170.85 1 37 -github.com/gocraft/work/enqueue.go:174.3,176.17 3 37 -github.com/gocraft/work/enqueue.go:170.85,172.4 1 0 -github.com/gocraft/work/enqueue.go:184.141,186.19 2 24 -github.com/gocraft/work/enqueue.go:191.2,192.16 2 24 -github.com/gocraft/work/enqueue.go:196.2,206.16 3 24 -github.com/gocraft/work/enqueue.go:210.2,210.50 1 24 -github.com/gocraft/work/enqueue.go:244.2,244.28 1 24 -github.com/gocraft/work/enqueue.go:186.19,189.3 2 17 -github.com/gocraft/work/enqueue.go:192.16,194.3 1 0 -github.com/gocraft/work/enqueue.go:206.16,208.3 1 0 -github.com/gocraft/work/enqueue.go:210.50,214.57 3 24 -github.com/gocraft/work/enqueue.go:218.3,224.21 6 24 -github.com/gocraft/work/enqueue.go:234.3,234.19 1 24 -github.com/gocraft/work/enqueue.go:241.3,241.54 1 24 -github.com/gocraft/work/enqueue.go:214.57,216.4 1 0 -github.com/gocraft/work/enqueue.go:224.21,228.4 1 17 -github.com/gocraft/work/enqueue.go:228.9,232.4 1 7 -github.com/gocraft/work/enqueue.go:234.19,239.4 3 8 -github.com/gocraft/work/log.go:5.38,7.2 1 31 diff --git a/heartbeater_test.go b/heartbeater_test.go index c72a03fe..eade1e4e 100644 --- a/heartbeater_test.go +++ b/heartbeater_test.go @@ -5,12 +5,13 @@ import ( "time" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestHeartbeater(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() tMock := int64(1425263409) setNowEpochSecondsMock(tMock) diff --git a/identifier_test.go b/identifier_test.go index ccf89dfd..f723fdac 100644 --- a/identifier_test.go +++ b/identifier_test.go @@ -3,6 +3,8 @@ package work import "testing" func TestMakeIdentifier(t *testing.T) { + t.Parallel() + id := makeIdentifier() if len(id) < 10 { t.Errorf("expected a string of length 10 at least") diff --git a/job_test.go b/job_test.go index aa6222f2..cbb5af6d 100644 --- a/job_test.go +++ b/job_test.go @@ -8,6 +8,8 @@ import ( ) func TestJobArgumentExtraction(t *testing.T) { + t.Parallel() + j := Job{} j.setArg("str1", "bar") @@ -88,6 +90,8 @@ func TestJobArgumentExtraction(t *testing.T) { } func TestJobArgumentExtractionBadString(t *testing.T) { + t.Parallel() + var testCases = []struct { key string val interface{} @@ -127,6 +131,8 @@ func TestJobArgumentExtractionBadString(t *testing.T) { } func TestJobArgumentExtractionBadBool(t *testing.T) { + t.Parallel() + var testCases = []struct { key string val interface{} @@ -167,6 +173,8 @@ func TestJobArgumentExtractionBadBool(t *testing.T) { } func TestJobArgumentExtractionBadInt(t *testing.T) { + t.Parallel() + var testCases = []struct { key string val interface{} @@ -213,6 +221,8 @@ func TestJobArgumentExtractionBadInt(t *testing.T) { } func TestJobArgumentExtractionBadFloat(t *testing.T) { + t.Parallel() + var testCases = []struct { key string val interface{} diff --git a/observer_test.go b/observer_test.go index e25d44a8..bcacdaa8 100644 --- a/observer_test.go +++ b/observer_test.go @@ -5,12 +5,13 @@ import ( "testing" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestObserverStarted(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() tMock := int64(1425263401) setNowEpochSecondsMock(tMock) @@ -32,7 +33,7 @@ func TestObserverStarted(t *testing.T) { func TestObserverStartedDone(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() tMock := int64(1425263401) setNowEpochSecondsMock(tMock) @@ -51,7 +52,7 @@ func TestObserverStartedDone(t *testing.T) { func TestObserverCheckin(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() observer := newObserver(ns, pool, "abcd") observer.start() @@ -78,7 +79,7 @@ func TestObserverCheckin(t *testing.T) { func TestObserverCheckinFromJob(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() observer := newObserver(ns, pool, "abcd") observer.start() diff --git a/periodic_enqueuer_test.go b/periodic_enqueuer_test.go index 913766bb..56026e32 100644 --- a/periodic_enqueuer_test.go +++ b/periodic_enqueuer_test.go @@ -5,13 +5,14 @@ import ( "time" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/robfig/cron/v3" "github.com/stretchr/testify/assert" ) func TestPeriodicEnqueuer(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) var pjs []*periodicJob @@ -98,8 +99,10 @@ func TestPeriodicEnqueuer(t *testing.T) { } func TestPeriodicEnqueuerSpawn(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) pe := newPeriodicEnqueuer(ns, pool, nil) diff --git a/priority_sampler_test.go b/priority_sampler_test.go index 6117601c..07b16813 100644 --- a/priority_sampler_test.go +++ b/priority_sampler_test.go @@ -35,6 +35,7 @@ func TestPrioritySampler(t *testing.T) { // make sure these numbers are roughly correct. note that probability is a thing. assert.True(t, c5 > (2*c2)) + // below test is indeterministic, will keep this as originally intended until we understand what this testing assert.True(t, float64(c2) > (1.5*float64(c1))) assert.True(t, c1 >= (total/13), fmt.Sprintf("c1 = %d total = %d total/13=%d", c1, total, total/13)) assert.True(t, float64(c1end) > (float64(total)*0.50)) diff --git a/requeuer_test.go b/requeuer_test.go index 5344da0c..4c3df430 100644 --- a/requeuer_test.go +++ b/requeuer_test.go @@ -3,12 +3,13 @@ package work import ( "testing" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestRequeue(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) tMock := nowEpochSeconds() - 10 @@ -51,7 +52,7 @@ func TestRequeue(t *testing.T) { func TestRequeueUnknown(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) tMock := nowEpochSeconds() - 10 diff --git a/run_test.go b/run_test.go index 5bf0d2c9..1dd976e2 100644 --- a/run_test.go +++ b/run_test.go @@ -9,6 +9,8 @@ import ( ) func TestRunBasicMiddleware(t *testing.T) { + t.Parallel() + mw1 := func(j *Job, next NextMiddlewareFunc) error { j.setArg("mw1", "mw1") return next() @@ -55,6 +57,8 @@ func TestRunBasicMiddleware(t *testing.T) { } func TestRunHandlerError(t *testing.T) { + t.Parallel() + mw1 := func(j *Job, next NextMiddlewareFunc) error { return next() } @@ -86,6 +90,8 @@ func TestRunHandlerError(t *testing.T) { } func TestRunMwError(t *testing.T) { + t.Parallel() + mw1 := func(j *Job, next NextMiddlewareFunc) error { return fmt.Errorf("mw1_err") } @@ -114,6 +120,8 @@ func TestRunMwError(t *testing.T) { } func TestRunHandlerPanic(t *testing.T) { + t.Parallel() + mw1 := func(j *Job, next NextMiddlewareFunc) error { return next() } @@ -143,6 +151,8 @@ func TestRunHandlerPanic(t *testing.T) { } func TestRunMiddlewarePanic(t *testing.T) { + t.Parallel() + mw1 := func(j *Job, next NextMiddlewareFunc) error { panic("dayam") } diff --git a/time.go b/time.go index 9b09234f..b12b880b 100644 --- a/time.go +++ b/time.go @@ -1,6 +1,8 @@ package work -import "time" +import ( + "time" +) var nowMock int64 diff --git a/webui/internal/assets/assets.go b/webui/internal/assets/assets.go index 2b99d409..afbe8190 100644 --- a/webui/internal/assets/assets.go +++ b/webui/internal/assets/assets.go @@ -162,7 +162,7 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ "index.html": indexHtml, - "work.js": workJs, + "work.js": workJs, } // AssetDir returns the file names below a certain @@ -204,9 +204,10 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } + var _bintree = &bintree{nil, map[string]*bintree{ - "index.html": &bintree{indexHtml, map[string]*bintree{}}, - "work.js": &bintree{workJs, map[string]*bintree{}}, + "index.html": {indexHtml, map[string]*bintree{}}, + "work.js": {workJs, map[string]*bintree{}}, }} // RestoreAsset restores an asset under the given directory @@ -255,4 +256,3 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } - diff --git a/webui/webui_test.go b/webui/webui_test.go index 850ac901..ece6ed87 100644 --- a/webui/webui_test.go +++ b/webui/webui_test.go @@ -11,12 +11,15 @@ import ( "github.com/gocraft/work" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestWebUIStartStop(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) s := NewServer(ns, pool, ":6666") @@ -27,8 +30,10 @@ func TestWebUIStartStop(t *testing.T) { type TestContext struct{} func TestWebUIQueues(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Get some stuff to to show up in the jobs: @@ -83,8 +88,10 @@ func TestWebUIQueues(t *testing.T) { } func TestWebUIWorkerPools(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) wp := work.NewWorkerPool(TestContext{}, 10, ns, pool) @@ -121,8 +128,10 @@ func TestWebUIWorkerPools(t *testing.T) { } func TestWebUIBusyWorkers(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) // Keep a job in the in-progress state without using sleeps @@ -183,8 +192,10 @@ func TestWebUIBusyWorkers(t *testing.T) { } func TestWebUIRetryJobs(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := work.NewEnqueuer(ns, pool) @@ -226,8 +237,10 @@ func TestWebUIRetryJobs(t *testing.T) { } func TestWebUIScheduledJobs(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := work.NewEnqueuer(ns, pool) @@ -259,8 +272,10 @@ func TestWebUIScheduledJobs(t *testing.T) { } func TestWebUIDeadJobs(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := work.NewEnqueuer(ns, pool) @@ -348,8 +363,10 @@ func TestWebUIDeadJobs(t *testing.T) { } func TestWebUIDeadJobsDeleteRetryAll(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := work.NewEnqueuer(ns, pool) @@ -450,8 +467,10 @@ func TestWebUIDeadJobsDeleteRetryAll(t *testing.T) { } func TestWebUIAssets(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "testwork" + ns := uuid.New().String() s := NewServer(ns, pool, ":6666") recorder := httptest.NewRecorder() diff --git a/worker_pool_test.go b/worker_pool_test.go index b2c47997..6a056cc7 100644 --- a/worker_pool_test.go +++ b/worker_pool_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) @@ -22,6 +23,8 @@ func (c *tstCtx) record(s string) { var tstCtxType = reflect.TypeOf(tstCtx{}) func TestWorkerPoolHandlerValidations(t *testing.T) { + t.Parallel() + var cases = []struct { fn interface{} good bool @@ -46,6 +49,8 @@ func TestWorkerPoolHandlerValidations(t *testing.T) { } func TestWorkerPoolMiddlewareValidations(t *testing.T) { + t.Parallel() + var cases = []struct { fn interface{} good bool @@ -72,8 +77,10 @@ func TestWorkerPoolMiddlewareValidations(t *testing.T) { } func TestWorkerPoolStartStop(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() wp := NewWorkerPool(TestContext{}, 10, ns, pool) wp.Start() wp.Start() @@ -84,8 +91,10 @@ func TestWorkerPoolStartStop(t *testing.T) { } func TestWorkerPoolValidations(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() wp := NewWorkerPool(TestContext{}, 10, ns, pool) func() { @@ -115,7 +124,7 @@ func TestWorkerPoolValidations(t *testing.T) { func TestWorkersPoolRunSingleThreaded(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" numJobs, concurrency, sleepTime := 5, 5, 2 wp := setupTestWorkerPool(pool, ns, job1, concurrency, JobOptions{Priority: 1, MaxConcurrency: 1}) diff --git a/worker_test.go b/worker_test.go index 11099249..72ea2dc0 100644 --- a/worker_test.go +++ b/worker_test.go @@ -8,12 +8,15 @@ import ( "time" "github.com/gomodule/redigo/redis" + "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestWorkerBasics(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" job2 := "job2" job3 := "job3" @@ -89,8 +92,10 @@ func TestWorkerBasics(t *testing.T) { } func TestWorkerInProgress(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" deleteQueue(pool, ns, job1) deleteRetryAndDead(pool, ns) @@ -142,8 +147,10 @@ func TestWorkerInProgress(t *testing.T) { } func TestWorkerRetry(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" deleteQueue(pool, ns, job1) deleteRetryAndDead(pool, ns) @@ -189,8 +196,10 @@ func TestWorkerRetry(t *testing.T) { // Check if a custom backoff function functions functionally. func TestWorkerRetryWithCustomBackoff(t *testing.T) { + t.Parallel() + pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" deleteQueue(pool, ns, job1) deleteRetryAndDead(pool, ns) @@ -240,7 +249,7 @@ func TestWorkerRetryWithCustomBackoff(t *testing.T) { func TestWorkerDead(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" job2 := "job2" deleteQueue(pool, ns, job1) @@ -303,7 +312,7 @@ func TestWorkerDead(t *testing.T) { func TestWorkersPaused(t *testing.T) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() job1 := "job1" deleteQueue(pool, ns, job1) deleteRetryAndDead(pool, ns) @@ -366,6 +375,8 @@ func TestWorkersPaused(t *testing.T) { // Test that in the case of an unavailable Redis server, // the worker loop exits in the case of a WorkerPool.Stop func TestStop(t *testing.T) { + t.Parallel() + redisPool := &redis.Pool{ Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", "notworking:6379", redis.DialConnectTimeout(1*time.Second)) @@ -382,7 +393,7 @@ func TestStop(t *testing.T) { func BenchmarkJobProcessing(b *testing.B) { pool := newTestPool() - ns := "work" + ns := uuid.New().String() cleanKeyspace(ns, pool) enqueuer := NewEnqueuer(ns, pool) @@ -597,7 +608,9 @@ type emptyCtx struct{} // drained before returning. // https://github.com/gocraft/work/issues/24 func TestWorkerPoolStop(t *testing.T) { - ns := "will_it_end" + t.Parallel() + + ns := uuid.New().String() pool := newTestPool() var started, stopped int32 numIters := 30 From 02465ff8689f34b850e2a46b0d64185b31603188 Mon Sep 17 00:00:00 2001 From: ardhi Date: Tue, 17 Nov 2020 12:00:19 +0700 Subject: [PATCH 4/7] deps cleanup --- go.mod | 1 - go.sum | 5 ----- 2 files changed, 6 deletions(-) diff --git a/go.mod b/go.mod index 58fe3633..c5548045 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.14 require ( github.com/braintree/manners v0.0.0-20160418043613-82a8879fc5fd - github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0 github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b github.com/gomodule/redigo v1.8.2 github.com/google/uuid v1.1.2 diff --git a/go.sum b/go.sum index 679a2dfa..1280b97e 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ github.com/braintree/manners v0.0.0-20160418043613-82a8879fc5fd h1:ePesaBzdTmoMQ github.com/braintree/manners v0.0.0-20160418043613-82a8879fc5fd/go.mod h1:TNehV1AhBwtT7Bd+rh8G6MoGDbBLNs/sKdk3nvr4Yzg= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0 h1:pKjeDsx7HGGbjr7VGI1HksxDJqSjaGED3cSw9GeSI98= -github.com/gocraft/health v0.0.0-20170925182251-8675af27fef0/go.mod h1:rWibcVfwbUxi/QXW84U7vNTcIcZFd6miwbt8ritxh/Y= github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b h1:g2Qcs0B+vOQE1L3a7WQ/JUUSzJnHbTz14qkJSqEWcF4= github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b/go.mod h1:Ag7UMbZNGrnHwaXPJOUKJIVgx4QOWMOWZngrvsN6qak= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= @@ -14,15 +12,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 3a05a292278ff742b3520b2397f7bcf39d4cc7d7 Mon Sep 17 00:00:00 2001 From: ardhi Date: Tue, 17 Nov 2020 12:00:43 +0700 Subject: [PATCH 5/7] add redis as docker container --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 8790bec9..9c18a9a5 100644 --- a/Makefile +++ b/Makefile @@ -29,3 +29,8 @@ test: mkdir -p ./etc/out ENVIRONMENT=test go test -failfast -count 1 -timeout 30s -covermode=atomic -coverprofile=etc/out/profile.cov ./... && go tool cover -func=etc/out/profile.cov +docker.start: docker.stop + docker run -d --rm -p 6379:6379 --name work-redis-server redis:latest || true + +docker.stop: + docker stop work-redis-server || true \ No newline at end of file From df56732f8cb1a304461e488919cc007881a0118f Mon Sep 17 00:00:00 2001 From: ardhi Date: Tue, 17 Nov 2020 12:00:57 +0700 Subject: [PATCH 6/7] remove unneeded cmds --- benches/bench_work/main.go | 129 ------------------------------------- cmd/workenqueue/main.go | 59 ----------------- cmd/workfakedata/main.go | 100 ---------------------------- 3 files changed, 288 deletions(-) delete mode 100644 benches/bench_work/main.go delete mode 100644 cmd/workenqueue/main.go delete mode 100644 cmd/workfakedata/main.go diff --git a/benches/bench_work/main.go b/benches/bench_work/main.go deleted file mode 100644 index 0b0593b7..00000000 --- a/benches/bench_work/main.go +++ /dev/null @@ -1,129 +0,0 @@ -package main - -import ( - "fmt" - "os" - "sync/atomic" - "time" - - "github.com/gocraft/health" - "github.com/gocraft/work" - "github.com/gomodule/redigo/redis" -) - -var namespace = "bench_test" -var pool = newPool(":6379") - -type context struct{} - -func epsilonHandler(job *work.Job) error { - //fmt.Println("hi") - //a := job.Args[0] - //fmt.Printf("job: %s arg: %v\n", job.Name, a) - atomic.AddInt64(&totcount, 1) - return nil -} - -func main() { - stream := health.NewStream().AddSink(&health.WriterSink{os.Stdout}) - cleanKeyspace() - - numJobs := 10 - jobNames := []string{} - - for i := 0; i < numJobs; i++ { - jobNames = append(jobNames, fmt.Sprintf("job%d", i)) - } - - job := stream.NewJob("enqueue_all") - enqueueJobs(jobNames, 10000) - job.Complete(health.Success) - - workerPool := work.NewWorkerPool(context{}, 20, namespace, pool) - for _, jobName := range jobNames { - workerPool.Job(jobName, epsilonHandler) - } - go monitor() - - job = stream.NewJob("run_all") - workerPool.Start() - workerPool.Drain() - job.Complete(health.Success) - select {} -} - -var totcount int64 - -func monitor() { - t := time.Tick(1 * time.Second) - - curT := 0 - c1 := int64(0) - c2 := int64(0) - prev := int64(0) - -DALOOP: - for range t { - curT++ - v := atomic.AddInt64(&totcount, 0) - fmt.Printf("after %d seconds, count is %d\n", curT, v) - if curT == 1 { - c1 = v - } else if curT == 3 { - c2 = v - } - if v == prev { - break DALOOP - } - prev = v - } - - fmt.Println("Jobs/sec: ", float64(c2-c1)/2.0) - os.Exit(0) -} - -func enqueueJobs(jobs []string, count int) { - enq := work.NewEnqueuer(namespace, pool) - for _, jobName := range jobs { - for i := 0; i < count; i++ { - enq.Enqueue(jobName, work.Q{"i": i}) - } - } -} - -func cleanKeyspace() { - conn := pool.Get() - defer conn.Close() - - keys, err := redis.Strings(conn.Do("KEYS", namespace+"*")) - if err != nil { - panic("could not get keys: " + err.Error()) - } - for _, k := range keys { - //fmt.Println("deleting ", k) - if _, err := conn.Do("DEL", k); err != nil { - panic("could not del: " + err.Error()) - } - } -} - -func newPool(addr string) *redis.Pool { - return &redis.Pool{ - MaxActive: 20, - MaxIdle: 20, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) - if err != nil { - return nil, err - } - return c, nil - //return redis.NewLoggingConn(c, log.New(os.Stdout, "", 0), "redis"), err - }, - Wait: true, - //TestOnBorrow: func(c redis.Conn, t time.Time) error { - // _, err := c.Do("PING") - // return err - //}, - } -} diff --git a/cmd/workenqueue/main.go b/cmd/workenqueue/main.go deleted file mode 100644 index 924f6ec8..00000000 --- a/cmd/workenqueue/main.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "encoding/json" - "flag" - "fmt" - "os" - "time" - - "github.com/gocraft/work" - "github.com/gomodule/redigo/redis" -) - -var redisHostPort = flag.String("redis", ":6379", "redis hostport") -var redisNamespace = flag.String("ns", "work", "redis namespace") -var jobName = flag.String("job", "", "job name") -var jobArgs = flag.String("args", "{}", "job arguments") - -func main() { - flag.Parse() - - if *jobName == "" { - fmt.Println("no job specified") - os.Exit(1) - } - - pool := newPool(*redisHostPort) - - var args map[string]interface{} - err := json.Unmarshal([]byte(*jobArgs), &args) - if err != nil { - fmt.Println("invalid args:", err) - os.Exit(1) - } - - en := work.NewEnqueuer(*redisNamespace, pool) - en.Enqueue(*jobName, args) -} - -func newPool(addr string) *redis.Pool { - return &redis.Pool{ - MaxActive: 20, - MaxIdle: 20, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) - if err != nil { - return nil, err - } - return c, nil - //return redis.NewLoggingConn(c, log.New(os.Stdout, "", 0), "redis"), err - }, - Wait: true, - //TestOnBorrow: func(c redis.Conn, t time.Time) error { - // _, err := c.Do("PING") - // return err - //}, - } -} diff --git a/cmd/workfakedata/main.go b/cmd/workfakedata/main.go deleted file mode 100644 index 2347cec0..00000000 --- a/cmd/workfakedata/main.go +++ /dev/null @@ -1,100 +0,0 @@ -package main - -import ( - "crypto/rand" - "flag" - "fmt" - "math/big" - "time" - - "github.com/gocraft/work" - "github.com/gomodule/redigo/redis" -) - -var redisHostPort = flag.String("redis", ":6379", "redis hostport") -var redisNamespace = flag.String("ns", "work", "redis namespace") - -func epsilonHandler(job *work.Job) error { - fmt.Println("epsilon") - time.Sleep(time.Second) - - n, err := rand.Int(rand.Reader, big.NewInt(2)) - if err != nil { - panic(err) - } - - if n.Int64() == 0 { - return fmt.Errorf("random error") - } - return nil -} - -type context struct{} - -func main() { - flag.Parse() - fmt.Println("Installing some fake data") - - pool := newPool(*redisHostPort) - cleanKeyspace(pool, *redisNamespace) - - // Enqueue some jobs: - go func() { - conn := pool.Get() - defer conn.Close() - conn.Do("SADD", *redisNamespace+":known_jobs", "foobar") - }() - - go func() { - for { - en := work.NewEnqueuer(*redisNamespace, pool) - for i := 0; i < 20; i++ { - en.Enqueue("foobar", work.Q{"i": i}) - } - - time.Sleep(1 * time.Second) - } - }() - - wp := work.NewWorkerPool(context{}, 5, *redisNamespace, pool) - wp.Job("foobar", epsilonHandler) - wp.Start() - - select {} -} - -func newPool(addr string) *redis.Pool { - return &redis.Pool{ - MaxActive: 20, - MaxIdle: 20, - IdleTimeout: 240 * time.Second, - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", addr) - if err != nil { - return nil, err - } - return c, nil - //return redis.NewLoggingConn(c, log.New(os.Stdout, "", 0), "redis"), err - }, - Wait: true, - //TestOnBorrow: func(c redis.Conn, t time.Time) error { - // _, err := c.Do("PING") - // return err - //}, - } -} - -func cleanKeyspace(pool *redis.Pool, namespace string) { - conn := pool.Get() - defer conn.Close() - - keys, err := redis.Strings(conn.Do("KEYS", namespace+"*")) - if err != nil { - panic("could not get keys: " + err.Error()) - } - for _, k := range keys { - if _, err := conn.Do("DEL", k); err != nil { - panic("could not del: " + err.Error()) - } - } -} From d4a3e640b93eca9b5bd5e4e0c7d148669dee53f6 Mon Sep 17 00:00:00 2001 From: ardhi Date: Tue, 17 Nov 2020 12:01:15 +0700 Subject: [PATCH 7/7] use mockable time --- enqueue.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/enqueue.go b/enqueue.go index 0d2f763e..c930bc73 100644 --- a/enqueue.go +++ b/enqueue.go @@ -2,7 +2,6 @@ package work import ( "sync" - "time" "github.com/gomodule/redigo/redis" ) @@ -155,7 +154,7 @@ func (e *Enqueuer) EnqueueUniqueInByKey(jobName string, secondsFromNow int64, ar func (e *Enqueuer) addToKnownJobs(conn redis.Conn, jobName string) error { needSadd := true - now := time.Now().Unix() + now := nowEpochSeconds() e.mtx.RLock() t, ok := e.knownJobs[jobName]