rake 检查是否已经运行

发布于 2024-12-03 02:17:58 字数 89 浏览 1 评论 0原文

仅当 rake 任务尚未运行时,是否可以以某种方式执行它, 我想使用 cron 来执行一些 rake 任务,但如果先前的调用未完成,则 rake 任务不应启动 谢谢

Is it possible somehow to execute rake task only if it is not running already,
I want to use cron for executing some rake tasks but rake task shouldn't start if previous call is not finished
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

同展鸳鸯锦 2024-12-10 02:17:58

我使用 lockrun 来防止 cron 任务多次运行(这仅在通过调用命令时有效)相同的 lockrun 调用,因此如果您需要防止各种调用路径,那么您需要寻找其他方法)。

在你的 crontab 中,你可以像这样调用它:

*/5 * * * * /usr/local/bin/lockrun --lockfile=/var/run/this_task.lockrun -- cd /my/path && RAILS_ENV=production bundle exec rake this:task

I use lockrun to prevent cron tasks from running multiple times (this only works when invoking the command through the same lockrun invocation, so if you need to protect from various invocation paths, then you'll need to look for other methods).

In your crontab, you invoke it like this:

*/5 * * * * /usr/local/bin/lockrun --lockfile=/var/run/this_task.lockrun -- cd /my/path && RAILS_ENV=production bundle exec rake this:task
小红帽 2024-12-10 02:17:58

另外,您可以使用锁文件,但在任务中处理它:

def lockfile
  # Assuming you're running Rails
  Rails.root.join('tmp', 'pids', 'leads_task.lock')
end

def running!
  `touch #{lockfile}`
end

def done!
  `rm #{lockfile}`
end

def running?
  File.exists?(lockfile)
end

task :long_running do
  unless running?
    running!
    # long running stuff
    done!
  end
end

这可能可以提取到某种模块中,但您明白了。

Also, you can use a lockfile, but handle it in the task:

def lockfile
  # Assuming you're running Rails
  Rails.root.join('tmp', 'pids', 'leads_task.lock')
end

def running!
  `touch #{lockfile}`
end

def done!
  `rm #{lockfile}`
end

def running?
  File.exists?(lockfile)
end

task :long_running do
  unless running?
    running!
    # long running stuff
    done!
  end
end

This probably could be extracted into some kind of module, but you get the idea.

遥远的绿洲 2024-12-10 02:17:58

一般的非 rake 特定解决方案是使用 pid 文件作为锁。您可以将 rake 任务包装在一个脚本中,该脚本在运行 rake 时创建此文件,在 rake 完成运行时删除它,并在开始之前检查它。

不确定 rake 是否有内置的东西,我什么都不知道。

The general non-rake specific solution to this is to use a pid file as a lock. You would wrap the rake task in a script that creates this file when it runs rake, removes it when rake finishes running, and checks for it before beginning.

Not sure if rake has something built in, I don't know of anything.

二智少女猫性小仙女 2024-12-10 02:17:58

如果您只是想跳过此 rake 任务,您还可以使用数据库来存储有关任务进度的信息(例如,在开始和完成给定任务时更新字段)并在运行每个任务之前检查该信息。

但是,如果您想要类似队列的行为,您可能需要考虑创建一个守护进程来处理任务。该过程非常简单,并且给您更多的控制权。有一个关于此的非常好的railscast: 自定义守护进程 守护

进程方法也会阻止rails环境避免在每个任务上再次加载。如果您的 rake 任务很频繁,这尤其有用。

If you simply want to skip this rake task, you could also use the database to store information about the task progress (e.g. update a field when you start and finish a given task) and check that information before running each task.

However, if you want a queue-like behavior, you might want to consider creating a daemon to handle the tasks. The process is very simple and gives you a lot more control. There is a very good railscast about this: Custom Daemon

The daemon approach will also prevent rails environment from being loaded again on each task. This is especially useful if your rake tasks are frequent.

听闻余生 2024-12-10 02:17:58

这是我的变体,带有用于 Rails rake 任务的文件锁。

将其放入您的 rake 任务文件中(在命名空间下,因此它不会与其他 rake 任务重叠):

def cron_lock(name)
  path = Rails.root.join('tmp', 'cron', "#{name}.lock")
  mkdir_p path.dirname unless path.dirname.directory?
  file = path.open('w')
  return if file.flock(File::LOCK_EX | File::LOCK_NB) == false
  yield
end

用法:

cron_lock 'namespace_task_name' do
  # your code
end

完整示例:

namespace :service do
  def cron_lock(name)
    path = Rails.root.join('tmp', 'cron', "#{name}.lock")
    mkdir_p path.dirname unless path.dirname.directory?
    file = path.open('w')
    return if file.flock(File::LOCK_EX | File::LOCK_NB) == false
    yield
  end

  desc 'description'
  task cleaning: :environment do
    cron_lock 'service_cleaning' do
      # your code
    end
  end
end

Here's my variant with file lock for rails rake tasks.

Put this in your rake task file (under namespace, so it wont overlap with other rake tasks):

def cron_lock(name)
  path = Rails.root.join('tmp', 'cron', "#{name}.lock")
  mkdir_p path.dirname unless path.dirname.directory?
  file = path.open('w')
  return if file.flock(File::LOCK_EX | File::LOCK_NB) == false
  yield
end

usage:

cron_lock 'namespace_task_name' do
  # your code
end

full example:

namespace :service do
  def cron_lock(name)
    path = Rails.root.join('tmp', 'cron', "#{name}.lock")
    mkdir_p path.dirname unless path.dirname.directory?
    file = path.open('w')
    return if file.flock(File::LOCK_EX | File::LOCK_NB) == false
    yield
  end

  desc 'description'
  task cleaning: :environment do
    cron_lock 'service_cleaning' do
      # your code
    end
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文