go使用Cron定时,实现recover机制。

16 阅读1分钟

robfig/cron v3 未实现recover

定时任务painc会导致程序内存数据丢失,发生重启,本教程是实现cron的recover机制。同样也适用于长连接场景,比如tcp链接后,用户发生行为调用rpc服务,但是在调用前的某些操作,被抽象出来了,编程不合理等场景,发生painc,会导致当前用户断开链接,数据丢失。

维护handler,defer 处理recover

type CornDesc struct {
    Name    string
    Spec    string
    NewFunc func()
}

func (c *CornDesc) Handle() {
    defer c.final()
    c.NewFunc()
}

func (c *CornDesc) final() {
    if err := recover(); err != nil {
       fmt.Printf("%s 捕获运行异常! err :%v stack %s\n", c.Name, err, debug.Stack())
    }
}

cmd 导入原则,此部分可以修改

var _Machine *Machine

type Machine struct {
    *cron.Cron
    exist map[string]int
}

func InitMachine(c *cron.Cron) *Machine {
    if _Machine == nil {
       _Machine = &Machine{
          Cron:  c,
          exist: make(map[string]int),
       }
    }
    return _Machine
}
func BaseMachine() *Machine {
    return _Machine
}
func (m *Machine) Run() {
    m.Cron.Run()
}
func (m *Machine) verify(cronDesc *CornDesc) error {
    if id, ok := m.exist[cronDesc.Name]; ok {
       return fmt.Errorf("任务已存在,name %s id %d", cronDesc.Name, id)
    }
    return nil
}
func (m *Machine) Register(cornDesc *CornDesc) error {
    if err := m.verify(cornDesc); err != nil {
       return err
    }
    id, err := m.Cron.AddFunc(cornDesc.Spec, cornDesc.Handle)
    if err != nil {
       return err
    }
    m.exist[cornDesc.Name] = int(id)
    return nil
}