Go使用gocron
排程(job scheduler)函式庫執行排程作業。
範例環境:
- Go 1.19
- github.com/go-co-op/gocron v1.27.1
安裝gocron
開啟命令列在專案根目錄輸入go get github.com/go-co-op/gocron
安裝gocron
。
% go get github.com/go-co-op/gocron
go: downloading github.com/go-co-op/gocron v1.27.1
go: downloading go.uber.org/atomic v1.9.0
go: added github.com/go-co-op/gocron v1.27.1
go: added github.com/robfig/cron/v3 v3.0.1
go: added go.uber.org/atomic v1.9.0
範例一
呼叫gocron.NewScheduler
建立gocron.Scheduler
物件,此為用來建立及操作排成的主要物件。
呼叫Scheduler.Every
設定排程執行的間隔單位數。
呼叫Scheduler.Seconds
設定排程執行的間隔單位為秒,其他還有Minutes
、Hours
等。
呼叫Scheduler.Do
設定排程要執行的邏輯,把邏輯放在函式做為第一個參數傳入。
呼叫Scheduler.StartAsync
以非同步方式啟動排程,即以另一條goroutine來執行。
main.go
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
sch := gocron.NewScheduler(time.UTC) // create a new job scheduler
count := 0
_, err := sch.Every(1).Seconds().Do(func() { // create a job to run function every 1 second
count++
fmt.Println(count)
})
if err != nil {
panic(err)
}
sch.StartAsync() // start the scheduler's jobs in another goroutine
time.Sleep(time.Second * 5) // main goroutine sleep for 5 second to let scheduler goroutine have time run
}
啟動Go程式,在console印出以下,每秒鐘印出遞增的數字1, 2, 3...。
1
2
3
4
5
範例二
呼叫Scheduler.Do
設定排程要執行的邏輯時,若函式有參數則可以第二個參數位置傳入,例如下面的"hello"即傳入為排程函式的參數param
。
呼叫Scheduler.StartBlocking
阻塞目前的goroutine並啟動排程,在這邊被阻塞的為main goroutine。
main.go
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
sch := gocron.NewScheduler(time.UTC)
count := 0
_, err := sch.Every(1).Second().Do(
func(param1 string) {
count++
fmt.Printf("%s-%d\n", param1, count)
}, "hello",
)
if err != nil {
panic(err)
}
sch.StartBlocking()
}
啟動Go程式,在console印出以下,每秒鐘印出以下。
hello-1
hello-2
hello-3
...
範例三
呼叫Scheduler.Cron
以cron表示式設定排程要執行的時間。
呼叫Scheduler.StartImmediately
立即執行排程邏輯。
main.go
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
sch := gocron.NewScheduler(time.UTC)
cronExp := "* * * * *" // cron expression: every minutes
_, err := sch.Cron(cronExp).StartImmediately().Do(
func(param1 string) {
fmt.Println("hello")
},
)
if err != nil {
panic(err)
}
sch.StartBlocking()
}
啟動Go程式,在console印出以下,執行後會立刻印出一個hello,接著每分鐘印出。
hello
hello
...
範例四
呼叫Scheduler.Stop
可停止排程。
main.go
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
sch := gocron.NewScheduler(time.UTC)
count := 0
_, err := sch.Every(1).Seconds().Do(func() {
count++
fmt.Println(count)
})
if err != nil {
panic(err)
}
sch.StartAsync()
time.Sleep(time.Second * 5)
sch.Stop() // stop scheduler
time.Sleep(time.Second * 2)
fmt.Println("end")
}
啟動Go程式,在console可能印出以下。
1
2
3
4
5
end
範例五
呼叫Scheduler.StartBlocking
時,透過channelchan *gocron.Scheduler
把Scheduler
傳遞到另一條goroutine(main)來呼叫Scheduler.Stop
停止排程。
main.go
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
schChan := make(chan *gocron.Scheduler)
go newJob(schChan)
sch := <-schChan
time.Sleep(5 * time.Second)
sch.Stop()
fmt.Println("end")
}
func newJob(schChan chan *gocron.Scheduler) {
sch := gocron.NewScheduler(time.UTC)
count := 0
_, err := sch.Every(1).Seconds().Do(func() {
count++
fmt.Println(count)
})
if err != nil {
panic(err)
}
schChan <- sch
sch.StartBlocking()
}
啟動Go程式,在console可能印出以下。
1
2
3
4
5
end
沒有留言:
張貼留言