func testPool(t *testing.T, duration time.Duration) { b, _, writer := SetupBroker(t) ticker := time.NewTicker(time.Millisecond * 10) go func() { for { select { case t := <-ticker.C: tk, _ := thermocline.NewTask(t) writer <- tk } } }() var worked int64 p, err := thermocline.NewPool("test", thermocline.NoVersion, b, func(task *thermocline.Task) ([]*thermocline.Task, error) { atomic.AddInt64(&worked, 1) time.Sleep(duration) return nil, nil }, 5) if err != nil { t.Errorf("cannot create pool %s", err) } time.Sleep(1 * time.Second) err = p.Add(120) if err != nil { t.Errorf("cannot add workers, %s", err) } time.Sleep(1 * time.Second) err = p.Add(-37) if err != nil { t.Errorf("cannot remove workers, %s", err) } time.Sleep(1 * time.Second) ticker.Stop() err = p.Stop() if err != nil { t.Errorf("cannot stop pool, %s", err) } if p.Len() != 0 { t.Errorf("pool length is not 0! - %d", p.Len()) } if a := atomic.LoadInt64(&worked); a <= 295 { t.Errorf("more than 295-ish tasks should be worked, %d", a) } }
func TestWorkerRetries(t *testing.T) { t.Parallel() var broker thermocline.Broker broker = mem.NewBroker() reader, err := broker.Read("test", thermocline.NoVersion) if err != nil { t.Errorf("could not open queue '%s'", err) } writer, err := broker.Write("test", thermocline.NoVersion) if err != nil { t.Errorf("could not open queue '%s'", err) } tn := rand.Intn(256) for i := range iter.N(tn) { task, err := thermocline.NewTask(fmt.Sprintf("test %d", i)) if err != nil { t.Error("could not create test task", err) } writer <- task } stopper := make(chan struct{}) var worked int64 wg := &sync.WaitGroup{} for range iter.N(rand.Intn(256)) { wg.Add(1) go thermocline.NewWorker(reader, writer, func(task *thermocline.Task) ([]*thermocline.Task, error) { atomic.AddInt64(&worked, 1) return nil, errors.New("cannot process task, herp derup") }, stopper).Work(wg) } time.Sleep(500 * time.Millisecond) close(stopper) wg.Wait() if atomic.LoadInt64(&worked) != int64(tn*3) { t.Errorf("%d tasks not worked in retry test after 500ms, actually %d", tn*3, atomic.LoadInt64(&worked)) } }
func TestWorker(t *testing.T) { t.Parallel() _, reader, writer := SetupBroker(t) tn := rand.Intn(256) //TODO(fortytw2): don't use iter for tests, even though it's nice for i := range iter.N(tn) { task, err := thermocline.NewTask(fmt.Sprintf("test %d", i)) if err != nil { t.Error("could not create test task", err) } writer <- task } stopper := make(chan struct{}) var worked int64 wg := &sync.WaitGroup{} for range iter.N(rand.Intn(256)) { wg.Add(1) go thermocline.NewWorker(reader, writer, func(task *thermocline.Task) ([]*thermocline.Task, error) { atomic.AddInt64(&worked, 1) return nil, nil }, stopper).Work(wg) } time.Sleep(500 * time.Millisecond) close(stopper) wg.Wait() if atomic.LoadInt64(&worked) != int64(tn) { t.Errorf("%d tasks not worked in basic test after 500ms, instead %d", tn, atomic.LoadInt64(&worked)) } }