github.com/bitleak/lmstfy@v1.0.13/engine/redis/timer_test.go (about) 1 package redis 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/sirupsen/logrus" 9 10 "github.com/bitleak/lmstfy/engine" 11 ) 12 13 func TestTimer_Add(t *testing.T) { 14 timer, err := NewTimer("timer_set_1", R, time.Second) 15 if err != nil { 16 panic(fmt.Sprintf("Failed to new timer: %s", err)) 17 } 18 job := engine.NewJob("ns-timer", "q1", []byte("hello msg 1"), 10, 0, 1, "") 19 if err = timer.Add(job.Namespace(), job.Queue(), job.ID(), 10, 1); err != nil { 20 t.Errorf("Failed to add job to timer: %s", err) 21 } 22 } 23 24 func TestTimer_Tick(t *testing.T) { 25 timer, err := NewTimer("timer_set_2", R, time.Second) 26 if err != nil { 27 panic(fmt.Sprintf("Failed to new timer: %s", err)) 28 } 29 defer timer.Shutdown() 30 job := engine.NewJob("ns-timer", "q2", []byte("hello msg 2"), 5, 0, 1, "") 31 pool := NewPool(R) 32 pool.Add(job) 33 timer.Add(job.Namespace(), job.Queue(), job.ID(), 3, 1) 34 errChan := make(chan error, 1) 35 go func() { 36 var err error = nil 37 defer func() { 38 // BRPop could panic 39 if r := recover(); r != nil { 40 err = fmt.Errorf("recover with panic %v", r) 41 } 42 errChan <- err 43 }() 44 val, err := R.Conn.BRPop(dummyCtx, 5*time.Second, join(QueuePrefix, "ns-timer", "q2")).Result() 45 if err != nil || len(val) == 0 { 46 err = fmt.Errorf("Failed to pop the job from target queue") 47 return 48 } 49 tries, jobID, err := structUnpack(val[1]) 50 if err != nil { 51 err = fmt.Errorf("Failed to decode the job pop from queue") 52 return 53 } 54 if tries != 1 || jobID != job.ID() { 55 err = fmt.Errorf("Job data mismatched") 56 return 57 } 58 }() 59 err = <-errChan 60 if err != nil { 61 t.Error(err) 62 } 63 } 64 65 func BenchmarkTimer(b *testing.B) { 66 // Disable logging temporarily 67 logger.SetLevel(logrus.ErrorLevel) 68 defer logger.SetLevel(logrus.DebugLevel) 69 70 t, err := NewTimer("timer_set_3", R, time.Second) 71 if err != nil { 72 panic(fmt.Sprintf("Failed to new timer: %s", err)) 73 } 74 defer t.Shutdown() 75 b.Run("Add", benchmarkTimer_Add(t)) 76 77 b.Run("Pop", benchmarkTimer_Pop(t)) 78 } 79 80 func benchmarkTimer_Add(timer *Timer) func(b *testing.B) { 81 pool := NewPool(R) 82 return func(b *testing.B) { 83 for i := 0; i < b.N; i++ { 84 job := engine.NewJob("ns-timer", "q3", []byte("hello msg 1"), 100, 0, 1, "") 85 pool.Add(job) 86 timer.Add(job.Namespace(), job.Queue(), job.ID(), 1, 1) 87 } 88 } 89 } 90 91 func benchmarkTimer_Pop(timer *Timer) func(b *testing.B) { 92 return func(b *testing.B) { 93 key := join(QueuePrefix, "ns-timer", "q3") 94 b.StopTimer() 95 pool := NewPool(R) 96 for i := 0; i < b.N; i++ { 97 job := engine.NewJob("ns-timer", "q3", []byte("hello msg 1"), 100, 0, 1, "") 98 pool.Add(job) 99 timer.Add(job.Namespace(), job.Queue(), job.ID(), 1, 1) 100 } 101 b.StartTimer() 102 for i := 0; i < b.N; i++ { 103 R.Conn.BRPop(dummyCtx, 5*time.Second, key) 104 } 105 } 106 } 107 108 // How long did it take to fire 10000 due jobs 109 func BenchmarkTimer_Pump(b *testing.B) { 110 // Disable logging temporarily 111 logger.SetLevel(logrus.ErrorLevel) 112 defer logger.SetLevel(logrus.DebugLevel) 113 114 b.StopTimer() 115 116 pool := NewPool(R) 117 timer, err := NewTimer("timer_set_4", R, time.Second) 118 if err != nil { 119 panic(fmt.Sprintf("Failed to new timer: %s", err)) 120 } 121 timer.Shutdown() 122 for i := 0; i < 10000; i++ { 123 job := engine.NewJob("ns-timer", "q4", []byte("hello msg 1"), 100, 0, 1, "") 124 pool.Add(job) 125 timer.Add(job.Namespace(), job.Queue(), job.ID(), 1, 1) 126 } 127 128 b.StartTimer() 129 timer.pump(time.Now().Unix() + 1) 130 }