Cron/Cronジョブ

概要

Cronはスケジューリングに関する機能で、ジョブの定期実行などで利用できます。 この機能は、例えばログローテーションなどに活用できます。

Cronに関する機能はztime/zcronパッケージにより提供されています。

機能

1. Cron式パース機能

本機能はCron式をパースする機能です。 Cron式には一般的な標準仕様が存在しないため、本機能は以下の仕様に従ってパースします。

Cron式のフォーマットは以下の通りです。 タイムゾーン、および秒フィールドの指定はオプショナルです。

TZ=UTC * * * * * *
|      | | | | | |
|      | | | | | |- Day of week
|      | | | | |--- Month
|      | | | |----- Day of month
|      | | |------- Hour
|      | |--------- Minute
|      |----------- Second (Optional)
|------------------ Timezone (Optional)

それぞれのフィールドは表に示した値を利用できます。 Day of monthDay of weekはAND条件で評価されます。

フィールド名指定必須特殊文字
TimezoneNoTimezone name
SecondNo0-59* / , -
MinuteYes0-59* / , -
HoursYes0-23* / , -
Day of monthYes1-31* / , -
MonthYes1-12 or JAN-DEC* / , -
Day of weekYes0-6 or SUN-SAT* / , -

エイリアス:

Cron式では以下のエイリアスを利用できます。 CRON_TZを除き、各エイリアスはその他のCron式と組み合わせて利用することはできません。

エイリアス名利用例
CRON_TZTZCRON_TZ=UTC 0 0 * * *
@monthly0 0 1 * *TZ=UTC @monthly
@weekly0 0 * * 0TZ=UTC @weekly
@daily0 0 * * *TZ=UTC @daily
@hourly0 * * * *TZ=UTC @hourly
@sunday0 0 * * 0TZ=UTC @sunday
@monday0 0 * * 1TZ=UTC @monday
@tuesday0 0 * * 2TZ=UTC @tuesday
@wednesday0 0 * * 3TZ=UTC @wednesday
@thursday0 0 * * 4TZ=UTC @thursday
@friday0 0 * * 5TZ=UTC @friday
@saturday0 0 * * 6TZ=UTC @saturday

every表記:

利便性のために、@every表記が用意されています。 この表記は1秒以上、24時間未満で定期的に実行する場合に利用できます。

なおパース可能な表記はGo標準パッケージのtime.Parseをご参照ください。

DurationResolved CronNotes
-1sERRORDuration must be >0
0sERRORDuration must be >0
1s*/1 * * * * *
1m0 */1 * * * *
1h0 0 */1 * * *
61s*/1 */1 * * *
15m30s*/30 */15 * * * *
65m30s*/30 */5 */1 * * *
1h30m0 */30 */1 * * *
23h59m59s*/59 */59 */23 * * *
24hERRORDuration must be <24h

2. スケジュール時刻決定機能

スケジュール時刻決定機能は、パースされたCron式によりスケジュールされる時刻を評価する機能です。 スケジュール時刻を取得する関数として以下の2つが用意されています。

Nextは現在時刻以降で最初にスケジュールされる時刻を返します。 NextAfterは指定されて時刻以降で最初にスケジュールされる時刻を返します。 なお、NextAfterにより返却される時刻のタイムゾーンは引数として受け取ったタイムゾーンになります。

基本的な利用方法はcronの基本的な利用を参照ください。

func Next() time.Time
func NextAfter(t time.Time) time.Time

3. ジョブ実行機能

ジョブ実行機能はCronによりスケジュールされた時刻にジョブを実行する機能です。 リスケジューリングなどの高度な機能は実装されていません。 デフォルトでは以下2つの項目を制御可能です。

  • 最大同時実行数: ある時刻で同時に起動しているジョブの最大数
  • 最大リトライ回数: ジョブが失敗した際にリトライする最大回数

基本的な利用方法はジョブ実行例を参照ください。

セキュリティに関する特記事項

セキュリティに関する特記事項はありません。

性能に関する特記事項

性能に関する特記事項はありません。

実装例・使い方

Cronの基本的な利用

cronの基本的な利用方法は以下のようになります。

package main

import (
	"fmt"
	"time"

	"github.com/aileron-projects/go/ztime/zcron"
)

func main() {
	// Working with the local time zone.
	cron, _ := zcron.Parse("* * * * *")
	fmt.Println("Next:", cron.Next())
	fmt.Println("Next After 1 hour:", cron.NextAfter(time.Now().Add(time.Hour)))
	fmt.Println("Next After 1 day:", cron.NextAfter(time.Now().Add(24*time.Hour)))

	// Working with a specific time zone.
	tzcron, _ := zcron.Parse("TZ=UTC * * * * *")
	fmt.Println("Next:", tzcron.Next())
	fmt.Println("Next After 1 hour:", tzcron.NextAfter(time.Now().UTC().Add(time.Hour)))
	fmt.Println("Next After 1 day:", tzcron.NextAfter(time.Now().UTC().Add(24*time.Hour)))
}

ジョブ実行例

ジョブの実行例は以下の通りです。 この例では3秒ごとに時刻を表示しています。 Startの実行ではGoroutineを利用していないので、Runを実行している行で処理はブロックされます。 ジョブを非同期で実行したい場合はgo cron.Start()のように実装します。

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/aileron-projects/go/ztime/zcron"
)

func main() {
	c := &zcron.Config{
		Crontab: "* */3 * * * * *", // every 3s.
		JobFunc: func(ctx context.Context) error {
			fmt.Println("It's", time.Now())
			return nil
		},
	}
	cron, err := zcron.NewCron(c)
	if err != nil {
		panic(err)
	}
	cron.Start()
}

参考資料