I'm trying to start and stop an infinite loop daemon using the daemons
gem.
Looking at the home page, I tried (in 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
Now, the exact example (#3 on the linked page) I'm looking at makes the first call with the option :multiple => true
, but I really only need one daemon to be running at a time (and multiple ones would, in fact, be undesirable).
Is the first daemon still somehow alive and not being GC'd? If so, what am I missing?
I think the misunderstanding here is that daemons do not run in order. By the nature of them, they run in parallel with very little coordination between them. I'm sure you could find Ruby interfaces to System V IPC semaphores to coordinate them, but if you want a job queue, look at something besides Daemons.
Also, to add to @Sigurd's answer above, here's the code in question that implements the :force
option (which is conveniently undocumented) (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
So basically, (zap
, as I found in the source, does absolutely nothing), when you specify :force
, Daemons will delete all non-running applications from @applications
if multiple isn't set. Otherwise, you get an error. So what that means is that if you don't specify :force
or :multiple
, your on a one way street to errors.
Note: The reason for all of this is that Application#stop
doesn't remove the Daemon from the ApplicationGroup
(which is in charge of creating new jobs).
Note: By the way, it's bad form in Ruby to use {}
for multiline blocks. Use {}
only for single line blocks. Use do...end
for multiline instead.