MCPcopy
hub / github.com/aceld/zinx / addTimer

Method addTimer

ztimer/timewheel.go:85–130  ·  view source on GitHub ↗

* 将一个timer定时器加入到分层时间轮中 tID: 每个定时器timer的唯一标识 t: 当前被加入时间轮的定时器 forceNext: 是否强制的将定时器添加到下一层时间轮 我们采用的算法是: 如果当前timer的超时时间间隔 大于一个刻度,那么进行hash计算 找到对应的刻度上添加 如果当前的timer的超时时间间隔 小于一个刻度 : 如果没有下一轮时间轮 */

(tID uint32, t *Timer, forceNext bool)

Source from the content-addressed store, hash-verified

83 如果没有下一轮时间轮
84*/
85func (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到一个时间轮中(非时间轮自转情况)
133func (tw *TimeWheel) AddTimer(tID uint32, t *Timer) error {

Callers 2

AddTimerMethod · 0.95
runMethod · 0.95

Calls 4

InsFunction · 0.92
UnixMilliFunction · 0.85
AddTimerMethod · 0.80
ErrorFMethod · 0.65

Tested by

no test coverage detected