這里寫了個定時任務(wù)調(diào)度的方案:由定時器去觸發(fā)一個job脉幢,job的執(zhí)行時間不定,需要有超時處理鸵隧。
這里使用content中的withTimeout處理(與自己起個超時判斷協(xié)程是一樣的效果),主程等待協(xié)程的job執(zhí)行豆瘫,成功/超時都繼續(xù)執(zhí)行下次運(yùn)行(當(dāng)然也可以超時后關(guān)閉這個定時任務(wù)也是可以的)
這是個簡單的定時小框架珊蟀,其有可能可完善成一個完整的定時調(diào)度工具外驱。
package main
import (
"context"
"fmt"
"math/rand"
"time"
)
func doJob(sig chan bool, timeout time.Duration) {
ctx, cancel := context.WithTimeout(context.Background(), timeout) //超時控制
defer cancel() //回調(diào)的方法入defer棧
done := make(chan bool)
go func(ctx context.Context) {
fmt.Printf("->%s Dooing the Job\n", time.Now().Format("2006-01-02 15:04:05"))
time.Sleep(time.Duration(rand.Intn(10)) * time.Second) //模擬一個隨機(jī)執(zhí)行時間的任務(wù)
fmt.Printf("<-%s Ending the Job\n\n", time.Now().Format("2006-01-02 15:04:05"))
done <- false
}(ctx)
select {
case <-done: //任務(wù)完成了
sig <- true
return
case <-ctx.Done(): //超時了
sig <- false
return
}
}
func doRunTicker(duration time.Duration, timeout time.Duration) {
sig := make(chan bool)
timer := time.NewTimer(duration)
for {
<-timer.C //等待定時器信號
go doJob(sig, timeout)
if x := <-sig; !x {
fmt.Printf("[E]%s 任務(wù)超時\n\n", time.Now().Format("2006-01-02 15:04:05"))
//return //關(guān)閉任務(wù)
}
timer.Reset(duration) //重置定時器,開始下次任務(wù)
}
}
func main() {
rand.Seed(time.Now().UnixNano())
doRunTicker(2*time.Second, 5*time.Second)
}