* 将一个timer定时器加入到分层时间轮中 tID: 每个定时器timer的唯一标识 t: 当前被加入时间轮的定时器 forceNext: 是否强制的将定时器添加到下一层时间轮 我们采用的算法是: 如果当前timer的超时时间间隔 大于一个刻度,那么进行hash计算 找到对应的刻度上添加 如果当前的timer的超时时间间隔 小于一个刻度 : 如果没有下一轮时间轮 */
(tID uint32, t *Timer, forceNext bool)
| 83 | 如果没有下一轮时间轮 |
| 84 | */ |
| 85 | func (tw *TimeWheel) addTimer(tID uint32, t *Timer, forceNext bool) error { |
| 86 | defer func() error { |
| 87 | if err := recover(); err != nil { |
| 88 | errstr := fmt.Sprintf("addTimer function err : %s", err) |
| 89 | zlog.Ins().ErrorF("addTimer function err : %s", err) |
| 90 | return errors.New(errstr) |
| 91 | } |
| 92 | return nil |
| 93 | }() |
| 94 | |
| 95 | //得到当前的超时时间间隔(ms)毫秒为单位 |
| 96 | delayInterval := t.unixts - UnixMilli() |
| 97 | |
| 98 | //如果当前的超时时间 大于一个刻度的时间间隔 |
| 99 | if delayInterval >= tw.interval { |
| 100 | //得到需要跨越几个刻度 |
| 101 | dn := delayInterval / tw.interval |
| 102 | //在对应的刻度上的定时器Timer集合map加入当前定时器(由于是环形,所以要求余) |
| 103 | tw.timerQueue[(tw.curIndex+int(dn))%tw.scales][tID] = t |
| 104 | |
| 105 | return nil |
| 106 | } |
| 107 | |
| 108 | //如果当前的超时时间,小于一个刻度的时间间隔,并且当前时间轮没有下一层,经度最小的时间轮 |
| 109 | if delayInterval < tw.interval && tw.nextTimeWheel == nil { |
| 110 | if forceNext == true { |
| 111 | //如果设置为强制移至下一个刻度,那么将定时器移至下一个刻度 |
| 112 | //这种情况,主要是时间轮自动轮转的情况 |
| 113 | //因为这是底层时间轮,该定时器在转动的时候,如果没有被调度者取走的话,该定时器将不会再被发现 |
| 114 | //因为时间轮刻度已经过去,如果不强制把该定时器Timer移至下时刻,就永远不会被取走并触发调用 |
| 115 | //所以这里强制将timer移至下个刻度的集合中,等待调用者在下次轮转之前取走该定时器 |
| 116 | tw.timerQueue[(tw.curIndex+1)%tw.scales][tID] = t |
| 117 | } else { |
| 118 | //如果手动添加定时器,那么直接将timer添加到对应底层时间轮的当前刻度集合中 |
| 119 | tw.timerQueue[tw.curIndex][tID] = t |
| 120 | } |
| 121 | return nil |
| 122 | } |
| 123 | |
| 124 | //如果当前的超时时间,小于一个刻度的时间间隔,并且有下一层时间轮 |
| 125 | if delayInterval < tw.interval { |
| 126 | return tw.nextTimeWheel.AddTimer(tID, t) |
| 127 | } |
| 128 | |
| 129 | return nil |
| 130 | } |
| 131 | |
| 132 | // AddTimer 添加一个timer到一个时间轮中(非时间轮自转情况) |
| 133 | func (tw *TimeWheel) AddTimer(tID uint32, t *Timer) error { |