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.
ngs/scheduler/scheduler.go

80 lines
1.1 KiB
Go

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
}