Ok, so here's the deal. RailsCron is still available, but in the not_supported folder of my svn.
Why?
- RailsCron is threaded, which causes all kinds of nightmares when Rails isn't threadsafe.
- All of RailsCron's functionality is available in BackgroundRb (which is threaded too, ymmv).
- RailsCron's daemonization isn't terribly Capistrano-friendly
- I wrote daemon_generator, which allows you to easily incorporate your own daemons into Rails. It's minimal, and it's what I actually use. Focusing on the daemons, without coupling messaging and database dependence, is the way to go for me.
If you want bare-bones, stable, and functional, use daemon_generator. If you want messaging and features, use backgroundRb. I don't see value in RailsCron anymore.
Ah. Well, I guess I'll switch then :P
Posted by: Hank | September 14, 2006 at 02:30 PM
We used railscron and it works reasonably well. With a few tweaks, it doesn't crash on our system any more. Not bad for a first attempt Kyle.
I agree that a general daemon framework is better though, so we may give the daemon_gen a try. Of course, it seems strange that a campus ministry would be creating daemons.
Posted by: Jack | September 15, 2006 at 05:13 PM
FYI, you can see it in action at http://www.PlaneFast.com
Posted by: Jack | September 15, 2006 at 05:16 PM
Ahh, this is great.
one issue with this way of doing things is that you must wait the sleep time to expire before the process actually dies. This is not good if you want your task to happen only once a day.
you can overcome this with the following:
term_check_duration = 10 #10 seconds
interval_in_seconds = 3600 # 1 hour
while($running) do
# Replace this with your code
if(skipped_total > interval_in_seconds)
skipped_total = 0
ActiveRecord::Base.logger << "This daemon is still running at #{Time.now}.\n"
end
sleep term_check_duration
skipped_total += term_check_duration
end
i haven't checked that code yet, but i think that should do the trick.
does your config/deploy.rb now contain something like the following?
desc "Stop daemons before deploying"
task :before_deploy do
run "#{current_path}/script/daemons stop"
end
desc "Start daemons after deploying"
task :after_deploy do
run "#{current_path}/script/daemons start"
end
thanks for the hard work!
Posted by: Aaron Blohowiak | September 17, 2006 at 08:47 PM
@Aaron:
The TERM signal causes the sleep to abort early, so the extra trickery you suggest is not needed.
The capistrano recipe looks similar to what I use.
Posted by: Kyle Maxwell | September 18, 2006 at 10:45 AM
Is daemon_generator *nix only? When I tried it on my Windows machine, I got the error:
lib/daemons/monitor.rb:61:in `fork': the fork() function is unimplemented on this machine (NotImplementedError)
Thanks.
Posted by: Ashish | September 19, 2006 at 07:05 AM
Yeah, it's *nix only.
Posted by: Kyle Maxwell | September 19, 2006 at 10:15 AM
I probably have done something wrong but I can't get script/generate daemon to work. I'm on Ubuntu 6.06.
I did:
sudo gem install daemons (succeeded)
rails app
cd app
script/generate daemon test
The generate statement fails with Couldn't find 'daemon' generator.
Did I miss something? I haven't installed any generators before - just used the stock rails generators.
Posted by: andrew | October 26, 2006 at 11:44 AM
I'm having the same problem as Andrew Carter above. Gem installed fine and then when I go to generate I get "Couldn't find 'daemon' generator" error.
Is there any solution to this? I am running in OS/X on Locomotive but will be deploying to a straight Unix box...
I'm baffled.
Posted by: Loren Johnson | October 26, 2006 at 04:55 PM
I am also running into the problem of not having a deamon generator.
I think gem might be installing:
http://gemjack.com/gems/daemons-1.0.1/index.html
Posted by: Dan Reverri | October 28, 2006 at 07:25 PM
Got ahold of Matt and got my problem figured-out. It seems I was missing a very critical step of installing his plugin. I think the daemon gem pre-existed this application and Matt's work is found in the following plugin installation after the daemon gem is hooked-up:
rails test
sudo gem install daemons
cd test
ruby script/plugin install
http://svn.kylemaxwell.com/rails_plugins/daemon_generator/trunk
ruby script/generate daemon tester
ruby script/daemons start
That got me there in a jiffy.
Thanks Matt and I hope that this helps someone else.
Posted by: Loren Johnson | November 01, 2006 at 02:06 PM
OOPS... the comment got fouled.. Here is the all critical line... replace the straight url above with this full command
ruby script/plugin install http://svn.kylemaxwell.com/rails_plugins/daemon_generator/trunk
Posted by: Loren Johnson | November 01, 2006 at 02:07 PM
OOPS... the comment got fouled.. Here is the all critical line... replace the straight url above with this full command
"ruby script/plugin install http://svn.kylemaxwell.com/rails_plugins/daemon_generator/trunk"
Posted by: Loren Johnson | November 01, 2006 at 02:08 PM
This seems to be working for me but when i go to stop the daemon I see this in my error log. The daemon doesn't seem to die gracefully. Can someone please let me know how to silence this. This is in my /log/#daemon#.rb.log.
failed to allocate memory
stack level too deep
exception reentered
no such file to load -- daemons
no such file to load -- openssl
no such file to load -- active_support
uninitialized constant Rails
no such file to load -- rails.rb
no such file to load -- tmail/base64.so
No such file or directory - /home/pb/sites/test/log/tester.rb.pid
no such file to load -- net/https
no such file to load -- http-access2
no such file to load -- xmlscan/scanner
no such file to load -- xml/parser
no such file to load -- tmail/scanner_c.so
Posted by: Paul | January 22, 2007 at 07:58 PM
I'm also having a problem running on OS X with Locomotive 2.0.8
This is what I get after creating the test daemon:
# Logfile created on Thu Jan 25 02:19:31 GMT 2007 by logger.rb/1.5.2.7
no such file to load -- daemons
failed to allocate memory
stack level too deep
exception reentered
no such file to load -- active_support
Posted by: Andri | January 24, 2007 at 07:05 PM
Hi all,
Apparently, daemon_generator doesn't like Rails 1.2. I'll try to issue a fix soon.
-Kyle
Posted by: Kyle Maxwell | January 24, 2007 at 08:52 PM
Any news on the fix? :)
Posted by: Andri | February 14, 2007 at 05:57 AM
Stupid me, I see it now ;p
Posted by: Andri | February 14, 2007 at 05:59 AM
Kyle, I'm looking for to using daemon generator but am having similar problems to those posted above:
no such file to load -- daemons
failed to allocate memory
... etc etc
I'm on Rails 1.2.2 and using daemon_generator 1.0.5.
thanks,
Russell
Posted by: Russell | March 02, 2007 at 11:14 AM
Anyone having the error with:
failed to allocate memory
stack level too deep
exception reentered
The problem is in your actual daemon script you wrote you have a signal handler for TERM. The variable gets changed from running to false, but the script keeps running because it is still sleeping. The simple solution is to just get rid of the signal handler and make it an infinite loop.
Hope this helps.
Posted by: Mark Loeser | March 06, 2007 at 02:08 PM
Same story, it's not working for me on Rails 1.2:
failed to allocate memory
stack level too deep
exception reentered
My entire customization of the generated code was adding a require statement on top, - one that I use a lot throughout the app.
Posted by: Vlad | March 28, 2007 at 08:30 AM
Hi every1,
I was able to install the generator, generate a daemon but apparently i am not able to start it. I get
script/daemons:2:in ``': No such file or directory - script/../lib/daemons/test_ctl start (Errno::ENOENT)
from script/daemons:2
from script/daemons:2
Am I missing something. Any help is appreciated.
Thank you
Posted by: jimache | April 05, 2007 at 10:31 AM
The bad thing about taking out the signal handler (which does seem to prevent the errors from occurring) is that any code after the loop doesn't run. In my case, that's only logging to indicate that the daemon terminated, so I can live with that.
Also, I'm not sure that you're guaranteed that the entire block will execute as a block, if the term signal comes in during processing of that block, which could be bad for some uses.
The errors only seem to occur at daemon startup, but then everything seems OK after that. Is that not the case?
Is there a less-simple but better solution?
Thanks!
Posted by: Lee Fyock | July 16, 2007 at 06:54 AM
Further googling shows in the Daemons docs for start_proc at :
175: # This part is needed to remove the pid-file if the application is killed by
176: # daemons or manually by the user.
177: # Note that the applications is not supposed to overwrite the signal handler for
178: # 'TERM'.
So, it looks like d_g shouldn't be generating code that traps TERM.
I'm trying to assess how dangerous it is for my purposes to have my routine just punted in the middle of execution when I restart the daemon. Most of its time will be spent sleeping, and it's probably no different than restarting the web server that's busy doing stuff...
Posted by: Lee Fyock | July 16, 2007 at 07:13 AM
For posterity...I'm now looking at OpenWFEru's scheduler, which looks pretty nice.
openwferu.rubyforge.org/scheduler.html
Posted by: Lee Fyock | August 10, 2007 at 11:06 AM