github.com/q191201771/naza@v0.30.12/pkg/taskpool/taskpool_test.go (about) 1 // Copyright 2019, Chef. All rights reserved. 2 // https://github.com/q191201771/naza 3 // 4 // Use of this source code is governed by a MIT-style license 5 // that can be found in the License file. 6 // 7 // Author: Chef (191201771@qq.com) 8 9 package taskpool_test 10 11 import ( 12 "github.com/q191201771/naza/pkg/nazaatomic" 13 "sync" 14 "sync/atomic" 15 "testing" 16 "time" 17 18 "github.com/q191201771/naza/pkg/taskpool" 19 20 "github.com/q191201771/naza/pkg/assert" 21 "github.com/q191201771/naza/pkg/nazalog" 22 ) 23 24 var ( 25 taskNum = 1000 * 1000 26 initWorkerNum = 1 //1000 * 20 //1000 * 10 27 ) 28 29 func BenchmarkOriginGo(b *testing.B) { 30 nazalog.Debug("> BenchmarkOriginGo") 31 var wg sync.WaitGroup 32 for j := 0; j < 1; j++ { 33 wg.Add(taskNum) 34 for i := 0; i < taskNum; i++ { 35 go func() { 36 time.Sleep(10 * time.Millisecond) 37 wg.Done() 38 }() 39 } 40 wg.Wait() 41 } 42 nazalog.Debug("< BenchmarkOriginGo") 43 } 44 45 func BenchmarkTaskPool(b *testing.B) { 46 nazalog.Debug("> BenchmarkTaskPool") 47 var wg sync.WaitGroup 48 p, _ := taskpool.NewPool(func(option *taskpool.Option) { 49 option.InitWorkerNum = initWorkerNum 50 }) 51 52 b.ResetTimer() 53 for j := 0; j < 1; j++ { 54 //b.StartTimer() 55 wg.Add(taskNum) 56 for i := 0; i < taskNum; i++ { 57 p.Go(func(param ...interface{}) { 58 time.Sleep(10 * time.Millisecond) 59 wg.Done() 60 }) 61 } 62 wg.Wait() 63 } 64 nazalog.Debug("< BenchmarkTaskPool") 65 } 66 67 func TestTaskPool(t *testing.T) { 68 var wg sync.WaitGroup 69 p, _ := taskpool.NewPool(func(option *taskpool.Option) { 70 option.InitWorkerNum = 1 71 }) 72 73 go func() { 74 //for { 75 nazalog.Debugf("timer, worker num. status=%+v", p.GetCurrentStatus()) 76 time.Sleep(10 * time.Millisecond) 77 //} 78 }() 79 80 n := 1000 81 wg.Add(n) 82 nazalog.Debug("start.") 83 for i := 0; i < n; i++ { 84 p.Go(func(param ...interface{}) { 85 time.Sleep(10 * time.Millisecond) 86 wg.Done() 87 }) 88 } 89 wg.Wait() 90 nazalog.Debugf("done, worker num. status=%+v", p.GetCurrentStatus()) // 此时还有个别busy也是正常的,因为只是业务方的任务代码执行完了,可能还没回收到idle队列中 91 p.KillIdleWorkers() 92 nazalog.Debugf("killed, worker num. status=%+v", p.GetCurrentStatus()) 93 94 time.Sleep(100 * time.Millisecond) 95 96 wg.Add(n) 97 for i := 0; i < n; i++ { 98 p.Go(func(param ...interface{}) { 99 time.Sleep(10 * time.Millisecond) 100 wg.Done() 101 }) 102 } 103 wg.Wait() 104 nazalog.Debugf("done, worker num. status=%+v", p.GetCurrentStatus()) 105 } 106 107 func TestMaxWorker(t *testing.T) { 108 p, err := taskpool.NewPool(func(option *taskpool.Option) { 109 option.MaxWorkerNum = 128 110 }) 111 assert.Equal(t, nil, err) 112 113 go func() { 114 for i := 0; i < 5; i++ { 115 nazalog.Debugf("timer. status=%+v", p.GetCurrentStatus()) 116 time.Sleep(100 * time.Millisecond) 117 } 118 }() 119 120 var wg sync.WaitGroup 121 var sum int32 122 n := 1000 123 wg.Add(n) 124 nazalog.Debugf("start.") 125 for i := 0; i < n; i++ { 126 p.Go(func(param ...interface{}) { 127 a := param[0].(int) 128 b := param[1].(int) 129 atomic.AddInt32(&sum, int32(a)) 130 atomic.AddInt32(&sum, int32(b)) 131 time.Sleep(10 * time.Millisecond) 132 wg.Done() 133 }, i, i) 134 } 135 wg.Wait() 136 nazalog.Debugf("end. sum=%d", sum) 137 } 138 139 func TestGlobal(t *testing.T) { 140 err := taskpool.Init() 141 assert.Equal(t, nil, err) 142 s := taskpool.GetCurrentStatus() 143 assert.Equal(t, 0, s.TotalWorkerNum) 144 assert.Equal(t, 0, s.IdleWorkerNum) 145 assert.Equal(t, 0, s.BlockTaskNum) 146 taskpool.Go(func(param ...interface{}) { 147 }) 148 taskpool.KillIdleWorkers() 149 } 150 151 func TestCorner(t *testing.T) { 152 _, err := taskpool.NewPool(func(option *taskpool.Option) { 153 option.InitWorkerNum = -1 154 }) 155 assert.Equal(t, taskpool.ErrTaskPool, err) 156 157 _, err = taskpool.NewPool(func(option *taskpool.Option) { 158 option.MaxWorkerNum = -1 159 }) 160 assert.Equal(t, taskpool.ErrTaskPool, err) 161 162 _, err = taskpool.NewPool(func(option *taskpool.Option) { 163 option.InitWorkerNum = 5 164 option.MaxWorkerNum = 1 165 }) 166 assert.Equal(t, taskpool.ErrTaskPool, err) 167 } 168 169 func TestPool_Dispose2(t *testing.T) { 170 // 测试 DisposeTypeRunAllBlockTask 171 172 tp, _ := taskpool.NewPool(func(option *taskpool.Option) { 173 option.InitWorkerNum = 2 174 option.MaxWorkerNum = 2 175 }) 176 177 var count nazaatomic.Int32 178 for i := 0; i < 10; i++ { 179 tp.Go(func(param ...interface{}) { 180 ii := param[0].(int) 181 time.Sleep(time.Duration(10) * time.Millisecond) 182 nazalog.Debugf("%d", ii) 183 count.Increment() 184 }, i) 185 } 186 187 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 188 tp.Dispose(taskpool.DisposeTypeRunAllBlockTask) 189 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 190 time.Sleep(200 * time.Millisecond) 191 assert.Equal(t, 10, int(count.Load())) 192 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 193 194 // 测试空闲情况dispose 195 { 196 tpp, _ := taskpool.NewPool(func(option *taskpool.Option) { 197 option.InitWorkerNum = 2 198 }) 199 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 200 tpp.Dispose(taskpool.DisposeTypeAsap) 201 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 202 } 203 } 204 205 func TestPool_Dispose(t *testing.T) { 206 tp, _ := taskpool.NewPool(func(option *taskpool.Option) { 207 option.InitWorkerNum = 1 208 option.MaxWorkerNum = 1 209 }) 210 211 var v nazaatomic.Int32 212 213 // 任务1在dispose之前已经被执行的任务,但是由于自身的sleep导致没有执行完,从而导致任务2,3在dispose时处于阻塞状态,还没有被执行 214 // 也因此,任务2,,3在dispose后不再执行 215 tp.Go(func(param ...interface{}) { 216 nazalog.Debugf("> task 1") 217 time.Sleep(100 * time.Millisecond) 218 nazalog.Debugf("< task 1") 219 v.Add(1) 220 }) 221 222 tp.Go(func(param ...interface{}) { 223 nazalog.Debugf("> task 2") 224 time.Sleep(300 * time.Millisecond) 225 nazalog.Debugf("< task 2") 226 v.Add(2) 227 }) 228 229 tp.Go(func(param ...interface{}) { 230 nazalog.Debugf("> task 3") 231 time.Sleep(500 * time.Millisecond) 232 nazalog.Debugf("< task 3") 233 v.Add(4) 234 }) 235 236 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 237 time.Sleep(50 * time.Millisecond) 238 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 239 tp.Dispose(taskpool.DisposeTypeAsap) 240 241 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 242 time.Sleep(400 * time.Millisecond) 243 244 tp.Dispose(taskpool.DisposeTypeAsap) 245 tp.Go(func(param ...interface{}) { 246 }) 247 tp.KillIdleWorkers() 248 nazalog.Debugf("%+v", tp.GetCurrentStatus()) 249 250 assert.Equal(t, 1, int(v.Load())) 251 }