golang 第三方定時任務庫 github.com/robfig/cron/v3 核心原始碼解讀
阿新 • • 發佈:2021-01-09
定時任務是一個通用場景的功能,在golang中,現在github最為常見的一個第三方定時任務庫就是 github.com/robfig/cron/v3 目前(2020年1月9日) 7.2k Star。
我之前使用Python的時候用慣了apscheduler
,切換這個是真的不習慣。
感覺github.com/robfig/cron/v3
功能太簡陋了,
- 不支援定時任務持久化,我重啟一下服務,排程任務資訊就沒了,需要自己儲存排程資訊。
- 再比如不支援一次定時見issue等,雖然有PR 但是 v3 分支還是依舊不支援,parse檔案函式不支援,雖然可以按照作者的說發,呼叫一次之後再呼叫移除可以實現。
- 不支援立即執行,
綜上,個人感覺這個庫封裝的不是很完善,作為一個golang新手,讀解析一下這個定時任務庫,還是很有收穫的。如果能力允許,以解決以上問題為目標,自己提PR。
注意
文章內容皆為個人見解,並且只看了核心的實現方式,細節部分沒有解析,不保證準確,如果和你的理解有歧義,以你的為準。
前置知識
你需要掌握golang的 goroutine
知識,包括channel
通訊,select
多路複用等知識,否則解讀起來就會很困難。
簡單的demo
更多使用demo可以參考 個人Go學習筆記
package _1_demo import ( "fmt" "github.com/robfig/cron/v3" "testing" "time" ) // 定時任務 func jobTask() { fmt.Printf( "任務啟動: %s \n",time.Now().Format("2006-01-02 15:04:05")) } func TestCron(t *testing.T) { // 建立一個cron物件 c := cron.New() // 任務排程 enterId, err := c.AddFunc("@every 3s", jobTask) if err!=nil{ panic(err) } fmt.Printf("任務id是 %d \n", enterId) // 啟動定時任務 c.Start() // 用於阻塞 後面可以使用 select {} 阻塞 time.Sleep(time.Second * 9) }
原始碼解讀
核心檔案主要就是cron.go
檔案
首先可以看到 c := cron.New()
建立了這個 Cron結構體物件
type Cron struct {
entries []*Entry // 用於存放job指標物件的陣列
chain Chain
stop chan struct{}
add chan *Entry
remove chan EntryID
snapshot chan chan []Entry
running bool // 保證
logger Logger
runningMu sync.Mutex
location *time.Location
parser ScheduleParser
nextID EntryID
jobWaiter sync.WaitGroup
}
排程任務enterId, err := c.AddFunc("@every 3s", jobTask)
會使用以下兩個檔案來解析定時執行的引數,也就是翻譯給golang 解析@erery 3s
是幹什麼
- https://github.com/robfig/cron/blob/v3/parser.go 解析自定義的定時引數 比如@erery等
- https://github.com/robfig/cron/blob/v3/spec.go 解析 crontab 表示式