monoの開発ブログ

golang で cron、setlock を添えて

golang で cron みたいなことをやるライブラリはすでに存在していて、使うだけの話ではあるんですけど、その際に setlock 的なものを噛ませたかったので書いてみました。プロセスを跨がなかったら簡単な話ですね。ただ、Mutex に TryLock 相当の機能が無かったので、ロックを獲得できなかったら処理しないバージョンについては Compare-and-Swap でやっています。

package main

import (
    "github.com/robfig/cron"
    "sync"
    "sync/atomic"
)

func main() {
    cron := cron.New()

    // setlock 風味
    // すでに実行中だったら終わるまで待ってから実行
    mutex := &sync.Mutex{}
    cron.AddFunc("* * * * *", func() {
        mutex.Lock()
        defer mutex.Unlock()

        // ...
    })

    // setlock -nx 風味
    // すでに実行中だったら何もせずに終了
    var running int32 = 0
    cron.AddFunc("* * * * *", func() {
        if atomic.CompareAndSwapInt32(&running, 0, 1) {
            defer atomic.StoreInt32(&running, 0)

            // ...
        }
    })

    cron.Start()

    select {}
}