我如何确保一次只运行一个Ruby脚本实例?

Jas*_*ler 8 ruby linux

我有一个每五分钟就在cron上运行一个进程.通常,运行只需几秒钟,但有时需要几分钟.我想确保一次只运行一个版本.

我试了一个明显的方法......

File.open("/tmp/indexer_lock.tmp",'w') do |f|
  exit unless f.flock(File::LOCK_EX)
end
Run Code Online (Sandbox Code Playgroud)

...但它没有测试它是否可以获得锁定,它会在锁定被释放之前阻塞.

知道我错过了什么吗?我宁愿不使用ps来破解某些东西,但这是另一种选择.

sma*_*thy 23

我知道这是旧的,但对于任何有兴趣的人,都有一个非阻塞常量可以传递给flock,以便它返回而不是阻塞.

File.new("/tmp/foo.lock").flock( File::LOCK_NB | File::LOCK_EX )
Run Code Online (Sandbox Code Playgroud)

更新slhck

flock如果进程收到锁定,则返回true ,否则返回false.因此,要确保一次只运行一个进程,您只想尝试获取锁定,如果无法执行则退出.它就像放在exit unless我上面的代码行前面一样简单:

exit unless File.new("/tmp/foo.lock").flock( File::LOCK_NB | File::LOCK_EX )
Run Code Online (Sandbox Code Playgroud)


Mat*_*odd 5

根据您的需要,这应该可以正常工作,并且不需要在任何地方创建另一个文件。

exit unless DATA.flock(File::LOCK_NB | File::LOCK_EX)

# your script here

__END__
DO NOT REMOVE: required for the DATA object above.
Run Code Online (Sandbox Code Playgroud)


小智 3

虽然这并没有直接回答您的问题,但如果我是您,我可能会编写一个守护程序脚本(您可以使用http://daemons.rubyforge.org/

您可以通过名为 script/index 的包装器脚本运行索引器(假设其 indexer.rb),例如:

require 'rubygems'
require 'daemons'

Daemons.run('indexer.rb')
Run Code Online (Sandbox Code Playgroud)

你的索引器几乎可以做同样的事情,除了你指定一个睡眠间隔

loop do
   # code executing your indexing 

   sleep INDEXING_INTERVAL
end
Run Code Online (Sandbox Code Playgroud)

这就是作业处理器与队列服务器通常协同工作的方式。