需要帮助防止多个 crons/调度程序在 golang 中运行

问题描述 投票:0回答:1

我正在开发一个 Go 微服务,我使用

robfig/cron
包来安排作业,最初想到使用 time.Ticker() 但包让我更容易。 我的问题是如何确保 cron 作业仅注册一次,直到运行的 cron 完成并防止多个 goroutine 同时运行。

这与单例方法不同,

RunProcess()
内的代码块必须在前面的 RunProcess 函数完成之前才能运行。

我是 golang 及其约定的新手。 :(

这是我当前实现的简化版本:

package main

import (
    "fmt"
    "sync"
    "time"

    "github.com/robfig/cron/v3"
)

var isProcessRunning = false
var mu sync.Mutex

func RunProcess() {
    mu.Lock()
    defer mu.Unlock()

    if isProcessRunning {
        fmt.Println("Already Running...")
        return
    }

    isProcessRunning = true
    fmt.Println("Running...")

    // Simulate work
    time.Sleep(15 * time.Second)
    isProcessRunning = false
}

func InitCron() {
    // Create a new cron scheduler
    c := cron.New(cron.WithSeconds())

    // Add the task to run every 10 seconds
    _, err := c.AddFunc("*/10 * * * * *", RunProcess)
    if err != nil {
        fmt.Println("Error adding cron job:", err)
        return
    }

    // Start the cron scheduler
    c.Start()

    // Block indefinitely to keep the cron jobs running
    select {}
}

func main() {
    InitCron()
}

但是,我注意到,当多次调用 InitCron 时,它可能会创建多个 cron 作业,从而导致轻量级微服务出现并发问题和意外行为。

任何有关如何正确管理此问题的建议或示例将不胜感激。

在 golang 中运行 cron 并尝试阻止 cron 直到第一个 cron 完成

go cron mutex
1个回答
0
投票

为了确保使用 robfig/cron 包的 Go 微服务中的 cron 作业仅注册一次并且不会同时运行多次,您可以利用 robfig/cron 的内置链接功能。如果前一个实例仍在运行,这将允许您使用作业包装器跳过作业执行。

这是您的实现的修订版本,它使用 robfig/cron 提供的 SkipIfStillRunning 作业包装器:

package main

import (
    "fmt"
    "time"

    "github.com/robfig/cron/v3"
)

func RunProcess() {
    fmt.Println("Running...")

    // Simulate work
    time.Sleep(15 * time.Second)

    fmt.Println("Completed...")
}

func InitCron() {
    // Create a new cron scheduler with a chain that skips the job if it's still running
    c := cron.New(cron.WithSeconds(), cron.WithChain(
        cron.SkipIfStillRunning(cron.DefaultLogger),
    ))

    // Add the task to run every 10 seconds
    _, err := c.AddFunc("*/10 * * * * *", RunProcess)
    if err != nil {
        fmt.Println("Error adding cron job:", err)
        return
    }

    // Start the cron scheduler
    c.Start()

    // Block indefinitely to keep the cron jobs running
    select {}
}

func main() {
    InitCron()
}
© www.soinside.com 2019 - 2024. All rights reserved.