kawasin73/htaskを使用したスケジューラの実装
基本的な使い方
func main() {
var wg sync.WaitGroup
workers := 1
c := cron.NewCron(&wg, cron.Option{
Workers: workers,
})
defer c.Close()
// 毎日1200に実行
c.Every(1).Day().At(12, 0).Run(func() {
fmt.Println("にゃーん")
})
// 毎日1900に実行
c.Every(1).Day().At(19, 0).Run(func() {
fmt.Println("わーい")
})
wg.Wait()
}
グレースフルシャットダウンを行うサンプル
func main() {
cronWg := new(sync.WaitGroup)
c := cron.NewCron(cronWg, cron.Option{
Workers: 1,
})
taskWg := new(sync.WaitGroup)
c.Every(1).Second().Run(func() {
for i := 0; i < 5; i++ {
taskWg.Add(1)
delay := time.Until(time.Now().Add(10 * time.Second))
time.AfterFunc(delay, func() {
defer taskWg.Done()
fmt.Println("にゃーん")
})
}
})
signals := make(chan os.Signal, 1)
defer close(signals)
signal.Notify(signals, syscall.SIGQUIT, syscall.SIGTERM, os.Interrupt)
<-signals
c.Close()
taskWg.Wait()
}
- 時間の掛かるタスクを実行している際、プログラムが終了されてしまうとタスクが中途半端な状態のまま終了してしまうことがある
- スケジューラで定期的に実行する処理はそれなりに処理時間が掛かるものが多く、中途半端な状態で終了されるのはよろしくない
- というわけで、シグナルでプログラムの終了を監視しつつ、タスクに
sync.WaitGroup
を与えることでタスクの完了待ちが出来るようにしている
参考資料