1 Star 0 Fork 0

nggs / micro

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
timer.go 3.41 KB
一键复制 编辑 原始数据 按行查看 历史
李文建 提交于 2020-04-04 21:04 . 移植microservice的代码
package actor
import (
"fmt"
"sync/atomic"
"time"
"github.com/AsynkronIT/protoactor-go/actor"
)
type TimerID = uint64
type Timeout struct {
ID TimerID
Tag TimerID
}
var gTagGenerator uint64
func GenerateTimerTag() TimerID {
//return TimerID(util.RandomInt64(math.MinInt64, math.MaxInt64))
return TimerID(atomic.AddUint64(&gTagGenerator, 1))
}
type TimerCallback func(id TimerID, tag TimerID)
type timer struct {
id TimerID
tag TimerID
cb TimerCallback
looped bool
stopCh chan struct{}
}
func (t *timer) stop() {
close(t.stopCh)
}
func (t *timer) trigger() {
t.cb(t.id, t.tag)
}
type TimerManager struct {
idGenerator uint64
timers map[TimerID]*timer
pid *actor.PID
}
func NewTimerManager(pid *actor.PID) *TimerManager {
return &TimerManager{
idGenerator: 0,
timers: make(map[TimerID]*timer),
pid: pid,
}
}
func (m *TimerManager) nextID() TimerID {
return TimerID(atomic.AddUint64(&m.idGenerator, 1))
}
func (m *TimerManager) NewTimer(dur time.Duration, callback TimerCallback) TimerID {
newTimer := &timer{
id: m.nextID(),
tag: 0,
cb: callback,
looped: false,
stopCh: make(chan struct{}),
}
m.timers[newTimer.id] = newTimer
go func() {
select {
case <-time.After(dur):
RootContext.Send(m.pid, &Timeout{newTimer.id, newTimer.tag})
case <-newTimer.stopCh:
return
}
}()
return newTimer.id
}
func (m *TimerManager) NewTimerWithTag(dur time.Duration, tag TimerID, callback TimerCallback) TimerID {
newTimer := &timer{
id: m.nextID(),
tag: tag,
cb: callback,
looped: false,
stopCh: make(chan struct{}),
}
m.timers[newTimer.id] = newTimer
go func() {
select {
case <-time.After(dur):
RootContext.Send(m.pid, &Timeout{newTimer.id, newTimer.tag})
case <-newTimer.stopCh:
return
}
}()
return newTimer.id
}
func (m *TimerManager) NewLoopTimer(dur time.Duration, callback TimerCallback) TimerID {
newTimer := &timer{
id: m.nextID(),
tag: 0,
cb: callback,
looped: true,
stopCh: make(chan struct{}),
}
m.timers[newTimer.id] = newTimer
go func() {
ticker := time.NewTicker(dur)
chTicker := ticker.C
msg := &Timeout{ID: newTimer.id, Tag: newTimer.tag}
for {
select {
case <-chTicker:
RootContext.Send(m.pid, msg)
case <-newTimer.stopCh:
ticker.Stop()
return
}
}
}()
return newTimer.id
}
func (m *TimerManager) NewLoopTimerWithTag(dur time.Duration, tag TimerID, callback TimerCallback) TimerID {
newTimer := &timer{
id: m.nextID(),
tag: tag,
cb: callback,
looped: true,
stopCh: make(chan struct{}),
}
m.timers[newTimer.id] = newTimer
go func() {
ticker := time.NewTicker(dur)
chTicker := ticker.C
msg := &Timeout{ID: newTimer.id, Tag: newTimer.tag}
for {
select {
case <-chTicker:
RootContext.Send(m.pid, msg)
case <-newTimer.stopCh:
ticker.Stop()
return
}
}
}()
return newTimer.id
}
func (m *TimerManager) Trigger(id TimerID) error {
t, ok := m.timers[id]
if !ok {
return fmt.Errorf("timer[%d] not found", id)
}
t.trigger()
if !t.looped {
delete(m.timers, id)
}
return nil
}
func (m *TimerManager) Stop(id TimerID) error {
if t, ok := m.timers[id]; ok {
t.stop()
delete(m.timers, id)
return nil
}
return fmt.Errorf("timer[%d] not found", id)
}
func (m *TimerManager) StopAll() {
for _, t := range m.timers {
t.stop()
}
// 清空map
m.timers = make(map[TimerID]*timer)
}
Go
1
https://gitee.com/nggs/micro.git
git@gitee.com:nggs/micro.git
nggs
micro
micro
bac99dff65eb

搜索帮助