我正在尝试使用daemons
gem来启动和停止无限循环守护进程。
看home page,我试过(在irb中):
require 'daemons'
=>true
task_handle = Daemons.call do
loop{
sleep 10
puts "foo"
}
end
=> #<Daemons::Application:0x000000043f96d0 ...
task_handle.stop
=> nil
task_handle2 = Daemons.call do
loop{
sleep 10
puts "bar"
}
end
=>Daemons::RuntimeException: there is already one or more instance(s) of the program running
from /home/bdares/.rvm/gems/ruby-1.9.3-p194/gems/daemons-1.1.9/lib/daemons/application_group.rb:125:in `new_application'
from /home/bdares/.rvm/gems/ruby-1.9.3-p194/gems/daemons-1.1.9/lib/daemons.rb:251:in `call'
from (irb):21
现在,我正在查看的确切示例(链接页面上的#3)使用选项:multiple => true
进行第一次调用,但我实际上只需要一个守护进程一次运行(并且多个事实上,这将是不受欢迎的。)
第一个守护进程是否还活着并且没有GC?如果是这样,我错过了什么?
答案 0 :(得分:1)
以下代码可以正常工作:
require 'daemons'
task_handle = Daemons.call(:force => true) do
loop{
sleep 10
puts "foo"
}
end
task_handle.stop
task_handle2 = Daemons.call do
loop{
sleep 10
puts "foo"
}
end
更改是在第一次调用:force
选项中。守护进程检查已创建的应用程序编号,而不仅仅是它们正在运行。在您的情况下,即使停止后第一个实例仍然存在。 “force”选项可清除未运行的应用程序。
请注意,您可能会遇到另一个问题 - task_handle.stop
并不能保证生成的proc会立即停止,因此您需要处理这种情况。
答案 1 :(得分:1)
我认为这里的误解是守护进程不按顺序运行。根据它们的性质,它们并行运行,它们之间的协调很少。我确信你可以找到与System V IPC信号量的Ruby接口来协调它们,但是如果你想要一个工作队列,那就看看守护进程以外的东西了。
另外,要添加@ Sigurd上面的答案,这里是有问题的代码实现了:force
选项(方便地没有记录)(source):
115: if @applications.size > 0 and not @multiple
116: if options[:force]
117: @applications.delete_if {|a|
118: unless a.running?
119: a.zap
120: true
121: end
122: }
123: end
124:
125: raise RuntimeException.new('there is already one or more instance(s) of the program running') unless @applications.empty?
126: end
所以基本上,(zap
,正如我在源代码中找到的那样绝对没有),当你指定:force
时,守护进程将删除所有未运行的应用程序如果未设置多个,则@applications
。否则,您会收到错误消息。那么这意味着如果你没有指定:force
或:multiple
,那么你就会在错误的单行道上。
注意:所有这一切的原因是Application#stop
不会从ApplicationGroup
(负责创建新工作)中移除守护程序。
注意:顺便说一句,Ruby中使用{}
表示多行块是不好的形式。仅对单行块使用{}
。使用do...end
代替多行。