網頁

2023/5/22

Golang gocron job scheduler 排程簡單範例

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設定排程執行的間隔單位為秒,其他還有MinutesHours等。

呼叫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
}

github


啟動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.SchedulerScheduler傳遞到另一條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


沒有留言:

張貼留言