You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
package scheduler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"git.noahlan.cn/northlan/ngs/internal/env"
|
|
|
|
"git.noahlan.cn/northlan/ngs/internal/log"
|
|
|
|
"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 {
|
|
|
|
log.Println(fmt.Sprintf("Handle message panic: %+v\n%s", err, debug.Stack()))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
f()
|
|
|
|
}
|
|
|
|
|
|
|
|
func Schedule() {
|
|
|
|
if atomic.AddInt32(&started, 1) != 1 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ticker := time.NewTicker(env.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
|
|
|
|
log.Println("Scheduler stopped")
|
|
|
|
}
|
|
|
|
|
|
|
|
func PushTask(task Task) {
|
|
|
|
chTasks <- task
|
|
|
|
}
|