package scheduler import ( "git.noahlan.cn/noahlan/ntool/nlog" "runtime/debug" "sync/atomic" "time" ) const ( messageQueueBacklog = 1 << 10 // 1024 sessionCloseBacklog = 1 << 8 // 256 ) // LocalScheduler schedules task to a customized goroutine type LocalScheduler interface { Schedule(Task) } type Task func() type Hook func() var ( chDie = make(chan struct{}) chExit = make(chan struct{}) chTasks = make(chan Task, 1<<8) started int32 closed int32 ) func try(f func()) { defer func() { if err := recover(); err != nil { nlog.Infof("Handle message panic: %+v\n%s", err, debug.Stack()) } }() f() } func Schedule(timerPrecision time.Duration) { if atomic.AddInt32(&started, 1) != 1 { return } if timerPrecision.Seconds() == 0 { timerPrecision = time.Second } ticker := time.NewTicker(timerPrecision) defer func() { ticker.Stop() close(chExit) }() for { select { case <-ticker.C: cron() case f := <-chTasks: try(f) case <-chDie: return } } } func Close() { if atomic.AddInt32(&closed, 1) != 1 { return } close(chDie) <-chExit nlog.Info("Scheduler stopped") } func PushTask(task Task) { chTasks <- task }