github.com/suiyunonghen/DxCommonLib@v0.5.3/TimeWheelingWorker.go_bak (about) 1 /* 2 时间轮询调度池,只用一个定时器来实现After等超时设定,默认轮渡器设定为1个小时,精度为500毫秒 3 Autor: 不得闲 4 QQ:75492895 5 */ 6 package DxCommonLib 7 8 import ( 9 "sync" 10 "time" 11 "sync/atomic" 12 ) 13 14 type ( 15 TimeWheelWorker struct { 16 sync.Mutex //调度锁 17 ticker *time.Ticker //调度器时钟 18 timeslocks []chan struct{} //时间槽 19 slockcount int 20 maxTimeout time.Duration 21 quitchan chan struct{} 22 curindex int //当前的索引 23 interval time.Duration 24 tkfunc func() 25 } 26 ) 27 28 var ( 29 defaultTimeWheelWorker *TimeWheelWorker 30 coarseTime atomic.Value //存放的是当前的实际时间 31 ) 32 33 //interval指定调度的时间间隔 34 //slotBlockCount指定时间轮的块长度 35 func NewTimeWheelWorker(interval time.Duration, slotBlockCount int,tkfunc func()) *TimeWheelWorker { 36 result := new(TimeWheelWorker) 37 result.interval = interval 38 result.quitchan = make(chan struct{}) 39 result.slockcount = slotBlockCount 40 result.tkfunc = tkfunc 41 result.maxTimeout = interval * time.Duration(slotBlockCount) 42 result.timeslocks = make([]chan struct{}, slotBlockCount) 43 result.ticker = time.NewTicker(interval) 44 go result.run() 45 return result 46 } 47 48 func (worker *TimeWheelWorker) run() { 49 for { 50 select { 51 case <-worker.ticker.C: 52 //执行定时操作 53 //获取当前的时间槽数据 54 worker.Lock() 55 lastC := worker.timeslocks[worker.curindex] 56 worker.timeslocks[worker.curindex] = make(chan struct{}) 57 worker.curindex = (worker.curindex + 1) % worker.slockcount 58 worker.Unlock() 59 if lastC != nil { 60 close(lastC) 61 } 62 if worker.tkfunc!=nil{ 63 worker.tkfunc() 64 } 65 case <-worker.quitchan: 66 worker.ticker.Stop() 67 return 68 } 69 } 70 } 71 72 func (worker *TimeWheelWorker) Stop() { 73 close(worker.quitchan) 74 } 75 76 func (worker *TimeWheelWorker) After(d time.Duration) <-chan struct{} { 77 if d >= worker.maxTimeout { 78 panic("timeout too much, over maxtimeout") 79 } 80 index := int(d / worker.interval) 81 if index > 0 { 82 index-- 83 } 84 worker.Lock() 85 index = (worker.curindex + index) % worker.slockcount 86 b := worker.timeslocks[index] 87 if b == nil { 88 b = make(chan struct{}) 89 worker.timeslocks[index] = b 90 } 91 worker.Unlock() 92 return b 93 } 94 95 func (worker *TimeWheelWorker)AfterFunc(d time.Duration,afunc func()) { 96 select{ 97 case <-worker.After(d): 98 afunc() 99 } 100 } 101 102 func (worker *TimeWheelWorker) Sleep(d time.Duration) { 103 select{ 104 case <-worker.After(d): 105 return 106 } 107 } 108 109 func After(d time.Duration) <-chan struct{} { 110 return defaultTimeWheelWorker.After(d) 111 } 112 113 func AfterFunc(d time.Duration,afunc func()) { 114 defaultTimeWheelWorker.AfterFunc(d,afunc) 115 } 116 117 func Sleep(d time.Duration) { 118 defaultTimeWheelWorker.Sleep(d) 119 } 120 121 func ReSetDefaultTimeWheel(Chkinterval time.Duration,slotBlockCount int){ 122 if defaultTimeWheelWorker.interval != Chkinterval || 123 defaultTimeWheelWorker.slockcount != slotBlockCount{ 124 defaultTimeWheelWorker.Stop() 125 defaultTimeWheelWorker = NewTimeWheelWorker(Chkinterval, slotBlockCount, func() { 126 t := time.Now().Truncate(Chkinterval) 127 coarseTime.Store(&t) 128 }) 129 } 130 } 131 132 133 func init() { 134 defaultTimeWheelWorker = NewTimeWheelWorker(time.Millisecond*500, 7200, func() { 135 t := time.Now().Truncate(time.Millisecond*500) 136 coarseTime.Store(&t) 137 }) 138 t := time.Now().Truncate(time.Millisecond*500) 139 coarseTime.Store(&t) 140 } 141 142 func CoarseTimeNow() time.Time { 143 tp := coarseTime.Load().(*time.Time) 144 return *tp 145 } 146