ruby-on-rails - 如何防止与 Rails 重叠 cron 作业?

标签 ruby-on-rails crontab race-condition whenever

我有一个 cron 作业设置,每 5 分钟运行一次任务。但有时该任务需要超过 5 分钟才能运行,因此该任务的另一个副本由 cron 同时运行。有没有办法在 when 或 cron 中让我们在运行另一个副本之前等待另一个作业完成?

最佳答案

AFAIK 您不能使用任何时候本身来执行此操作,但您可以在脚本中处理此问题。
这可以通过以下解决方案之一完成

  • 使用标志(或一些信息,如开始时间、结束时间、成功状态)在数据库中处理此问题,该标志在作业开始时设置并在作业结束时清除,并在每次作业开始时检查此标志以查看前一个作业是否是完成与否;但请确保在清除标志之前处理异常,就像进程死亡一样,没有其他进程能够运行
  • 您可以通过创建一个临时文件并为当前进程在其上设置排他锁,从而使操作系统作为您的标志工作,因此在当前进程完成之前,没有其他进程可以对该文件拥有排他锁,然后当进程完成它会释放锁并让其他进程工作。这样做包括这是你的 cron 工作的首要任务
    file = File.new("cron.lock", "a")
    can_lock = file.flock(File::LOCK_EX | File::LOCK_NB)
    
    if can_lock == false
      exit 1
    else
      #do whatever you want
    end
    

  • 第二种方法的优点是,即使进程意外终止,操作系统也会自动释放锁

    对我来说,我选择了第一种方法,因为如果前一个过程完成或花费的时间超过特定时间限制,我需要启动另一个过程

    有关更多详细信息,请查看 this link

    关于ruby-on-rails - 如何防止与 Rails 重叠 cron 作业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13131627/

    相关文章:

    javascript - jQuery $(window).load 没有按预期工作

    linux - 如何在 CentOS7 中更改 crontab 的默认编辑器?

    python - 使用 python 运行 crontab

    c++ - C++ 中良性竞争条件的保证

    java - Java 是否存在像 CHESS 这样的东西?

    java - 并行运行器跳过测试内的循环迭代

    ruby-on-rails - 清除旧的 Rails 迁移文件是个好主意吗?

    ruby-on-rails - Rails 连接查询

    ruby-on-rails - 这个 Ruby 函数在做什么?

    mysql - 使用 Cron Job 进行每日数据库备份