I followed the instructions at http://railscasts.com/episodes/129-custom-daemon
for creating a daemon. Simple enough, right? Wrong...
For some reason, I keep getting an error when running the daemon even
if I remove all my custom code from the generated code. Anybody know
what I''m doing wrong??
The error and the daemon code is at http://pastie.org/456601 as well
as below:
************************
The error (from log/mailer.rb.log):
************************
# Logfile created on Thu Apr 23 19:06:31 -0700 2009 by /
*** below you find the most recent exception thrown, this will be
likely (but not certainly) the exception that made the application
exit abnormally ***
#<Errno::ENOENT: No such file or directory - ./lib/daemons/../../
vendor/rails/activesupport/lib/active_support/locale/en.yml>
*** below you find all exception objects found in memory, some of them
may have been thrown in your application, others may just be in memory
because they are standard exceptions ***
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<Errno::ENOENT: No such file or directory - ./lib/daemons/../../
vendor/rails/activesupport/lib/active_support/locale/en.yml>
************************
lib/daemons/mailer.rb
************************
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= "production"
require File.dirname(__FILE__) + "/../../config/environment"
$running = true
Signal.trap("TERM") do
$running = false
end
while($running) do
# I removed my custom code to test whether the error was a result of
what I
# was trying to do, and the error still appears. The rest of the
code here
# was created by the daemon_generator plugin.
sleep 10
end
************************
lib/daemons/mailer_ctl
Again, no custom code here
************************
#!/usr/bin/env ruby
require ''rubygems''
require "daemons"
require ''yaml''
require ''erb''
file_name = File.dirname(__FILE__) + "/../../vendor/rails/
activesupport/lib/active_support.rb"
if(File.exists?(file_name))
require file_name
else
rails_version = File.new(File.dirname(__FILE__)+ "/../../config/
environment.rb").read.scan(/^
*RAILS_GEM_VERSION.*=.*[''|"](.*)[''|"]/)
[0].to_s
gem ''activesupport'', rails_version
require ''active_support''
end
options = YAML.load(
ERB.new(
IO.read(
File.dirname(__FILE__) + "/../../config/daemons.yml"
)).result).with_indifferent_access
options[:dir_mode] = options[:dir_mode].to_sym
Daemons.run File.dirname(__FILE__) + ''/mailer.rb'', options
************************
lib/daemon.rb
************************
# Taken from http://snippets.dzone.com/posts/show/2265
require ''fileutils''
module Daemon
WorkingDirectory = File.join(File.dirname(__FILE__), ''..'')
class Base
def self.pid_fn
File.join(WorkingDirectory, "log", "#{name}.pid")
end
def self.daemonize
Controller.daemonize(self)
end
end
module PidFile
def self.store(daemon, pid)
File.open(daemon.pid_fn, ''w'') {|f| f << pid}
end
def self.recall(daemon)
IO.read(daemon.pid_fn).to_i rescue nil
end
end
module Controller
def self.daemonize(daemon)
case !ARGV.empty? && ARGV[0]
when ''start''
start(daemon)
when ''stop''
stop(daemon)
when ''restart''
stop(daemon)
start(daemon)
else
puts "Invalid command. Please specify start, stop or restart."
exit
end
end
def self.start(daemon)
fork do
Process.setsid
exit if fork
PidFile.store(daemon, Process.pid)
Dir.chdir WorkingDirectory
File.umask 0000
STDIN.reopen "/dev/null"
#STDOUT.reopen "/dev/null", "a"
STDERR.reopen STDOUT
trap("TERM") {daemon.stop; exit}
daemon.start
end
end
def self.stop(daemon)
if !File.file?(daemon.pid_fn)
puts "Pid file not found. Is the daemon started?"
exit
end
pid = PidFile.recall(daemon)
FileUtils.rm(daemon.pid_fn)
pid && Process.kill("TERM", pid)
end
end
end
I forgot to mention that I checked and the file mentioned in the error is in that directory. Not sure why Rails thinks it''s missing... On Apr 23, 7:22 pm, gaveeno <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I followed the instructions athttp://railscasts.com/episodes/129-custom-daemon > for creating a daemon. Simple enough, right? Wrong... > > For some reason, I keep getting an error when running the daemon even > if I remove all my custom code from the generated code. Anybody know > what I''m doing wrong?? > > The error and the daemon code is athttp://pastie.org/456601as well > as below: > > ************************ > The error (from log/mailer.rb.log): > ************************ > > # Logfile created on Thu Apr 23 19:06:31 -0700 2009 by / > *** below you find the most recent exception thrown, this will be > likely (but not certainly) the exception that made the application > exit abnormally *** > #<Errno::ENOENT: No such file or directory - ./lib/daemons/../../ > vendor/rails/activesupport/lib/active_support/locale/en.yml> > *** below you find all exception objects found in memory, some of them > may have been thrown in your application, others may just be in memory > because they are standard exceptions *** > #<NoMemoryError: failed to allocate memory> > #<SystemStackError: stack level too deep> > #<fatal: exception reentered> > #<Errno::ENOENT: No such file or directory - ./lib/daemons/../../ > vendor/rails/activesupport/lib/active_support/locale/en.yml> > > ************************ > lib/daemons/mailer.rb > ************************ > #!/usr/bin/env ruby > > ENV["RAILS_ENV"] ||= "production" > > require File.dirname(__FILE__) + "/../../config/environment" > > $running = true > Signal.trap("TERM") do > $running = false > end > > while($running) do > > # I removed my custom code to test whether the error was a result of > what I > # was trying to do, and the error still appears. The rest of the > code here > # was created by the daemon_generator plugin. > > sleep 10 > end > > ************************ > lib/daemons/mailer_ctl > Again, no custom code here > ************************ > > #!/usr/bin/env ruby > require ''rubygems'' > require "daemons" > require ''yaml'' > require ''erb'' > > file_name = File.dirname(__FILE__) + "/../../vendor/rails/ > activesupport/lib/active_support.rb" > > if(File.exists?(file_name)) > require file_name > else > rails_version = File.new(File.dirname(__FILE__)+ "/../../config/ > environment.rb").read.scan(/^ *RAILS_GEM_VERSION.*=.*[''|"](.*)[''|"]/) > [0].to_s > > gem ''activesupport'', rails_version > require ''active_support'' > end > > options = YAML.load( > ERB.new( > IO.read( > File.dirname(__FILE__) + "/../../config/daemons.yml" > )).result).with_indifferent_access > options[:dir_mode] = options[:dir_mode].to_sym > > Daemons.run File.dirname(__FILE__) + ''/mailer.rb'', options > > ************************ > lib/daemon.rb > ************************ > > # Taken fromhttp://snippets.dzone.com/posts/show/2265 > > require ''fileutils'' > > module Daemon > WorkingDirectory = File.join(File.dirname(__FILE__), ''..'') > > class Base > def self.pid_fn > File.join(WorkingDirectory, "log", "#{name}.pid") > end > > def self.daemonize > Controller.daemonize(self) > end > end > > module PidFile > def self.store(daemon, pid) > File.open(daemon.pid_fn, ''w'') {|f| f << pid} > end > > def self.recall(daemon) > IO.read(daemon.pid_fn).to_i rescue nil > end > end > > module Controller > def self.daemonize(daemon) > case !ARGV.empty? && ARGV[0] > when ''start'' > start(daemon) > when ''stop'' > stop(daemon) > when ''restart'' > stop(daemon) > start(daemon) > else > puts "Invalid command. Please specify start, stop or restart." > exit > end > end > > def self.start(daemon) > fork do > Process.setsid > exit if fork > PidFile.store(daemon, Process.pid) > Dir.chdir WorkingDirectory > File.umask 0000 > STDIN.reopen "/dev/null" > #STDOUT.reopen "/dev/null", "a" > STDERR.reopen STDOUT > trap("TERM") {daemon.stop; exit} > daemon.start > end > end > > def self.stop(daemon) > if !File.file?(daemon.pid_fn) > puts "Pid file not found. Is the daemon started?" > exit > end > pid = PidFile.recall(daemon) > FileUtils.rm(daemon.pid_fn) > pid && Process.kill("TERM", pid) > end > end > end
I''ve found a solution that works for me -- not sure if it''s the "right" way to fix this but it does the job. I changed the directory settings in config/daemons.yml to: dir_mode: normal dir: (used to be dir_mode: script and dir: ../../log) I then expanded some of the paths used in mailer_ctl, and inserted some code to populate the "dir" option (which was blank in the YML file) with the expanded path of the log directory if the "dir_mode" option is set to "normal". #!/usr/bin/env ruby require ''rubygems'' require "daemons" require ''yaml'' require ''erb'' ######## #EXPAND PATH ######## file_name = File.expand_path(File.dirname(__FILE__) + "/../../vendor/ rails/activesupport/lib/active_support.rb") if(File.exists?(file_name)) require file_name else rails_version = File.new(File.dirname(__FILE__) + "/../../config/ environment.rb").read.scan(/^ *RAILS_GEM_VERSION.*=.*[''|"](.*)[''|"]/) [0].to_s gem ''activesupport'', rails_version require ''active_support'' end ######## #EXPAND PATH ######## options = YAML.load( ERB.new( IO.read( File.expand_path(File.dirname(__FILE__) + "/../../config/ daemons.yml") )).result).with_indifferent_access options[:dir_mode] = options[:dir_mode].to_sym ######## #EXPAND PATH OF LOG DIRECTORY ######## if options[:dir_mode] == :normal options[:dir] = File.expand_path(File.dirname(__FILE__) + "/../../ log/") end Daemons.run File.dirname(__FILE__) + ''/mailer.rb'', options On Apr 24, 9:01 am, gaveeno <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I forgot to mention that I checked and the file mentioned in the error > is in that directory. Not sure why Rails thinks it''s missing... > > On Apr 23, 7:22 pm, gaveeno <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I followed the instructions athttp://railscasts.com/episodes/129-custom-daemon > > for creating a daemon. Simple enough, right? Wrong... > > > For some reason, I keep getting an error when running the daemon even > > if I remove all my custom code from the generated code. Anybody know > > what I''m doing wrong?? > > > The error and the daemon code is athttp://pastie.org/456601aswell > > as below: > > > ************************ > > The error (from log/mailer.rb.log): > > ************************ > > > # Logfile created on Thu Apr 23 19:06:31 -0700 2009 by / > > *** below you find the most recent exception thrown, this will be > > likely (but not certainly) the exception that made the application > > exit abnormally *** > > #<Errno::ENOENT: No such file or directory - ./lib/daemons/../../ > > vendor/rails/activesupport/lib/active_support/locale/en.yml> > > *** below you find all exception objects found in memory, some of them > > may have been thrown in your application, others may just be in memory > > because they are standard exceptions *** > > #<NoMemoryError: failed to allocate memory> > > #<SystemStackError: stack level too deep> > > #<fatal: exception reentered> > > #<Errno::ENOENT: No such file or directory - ./lib/daemons/../../ > > vendor/rails/activesupport/lib/active_support/locale/en.yml> > > > ************************ > > lib/daemons/mailer.rb > > ************************ > > #!/usr/bin/env ruby > > > ENV["RAILS_ENV"] ||= "production" > > > require File.dirname(__FILE__) + "/../../config/environment" > > > $running = true > > Signal.trap("TERM") do > > $running = false > > end > > > while($running) do > > > # I removed my custom code to test whether the error was a result of > > what I > > # was trying to do, and the error still appears. The rest of the > > code here > > # was created by the daemon_generator plugin. > > > sleep 10 > > end > > > ************************ > > lib/daemons/mailer_ctl > > Again, no custom code here > > ************************ > > > #!/usr/bin/env ruby > > require ''rubygems'' > > require "daemons" > > require ''yaml'' > > require ''erb'' > > > file_name = File.dirname(__FILE__) + "/../../vendor/rails/ > > activesupport/lib/active_support.rb" > > > if(File.exists?(file_name)) > > require file_name > > else > > rails_version = File.new(File.dirname(__FILE__)+ "/../../config/ > > environment.rb").read.scan(/^ *RAILS_GEM_VERSION.*=.*[''|"](.*)[''|"]/) > > [0].to_s > > > gem ''activesupport'', rails_version > > require ''active_support'' > > end > > > options = YAML.load( > > ERB.new( > > IO.read( > > File.dirname(__FILE__) + "/../../config/daemons.yml" > > )).result).with_indifferent_access > > options[:dir_mode] = options[:dir_mode].to_sym > > > Daemons.run File.dirname(__FILE__) + ''/mailer.rb'', options > > > ************************ > > lib/daemon.rb > > ************************ > > > # Taken fromhttp://snippets.dzone.com/posts/show/2265 > > > require ''fileutils'' > > > module Daemon > > WorkingDirectory = File.join(File.dirname(__FILE__), ''..'') > > > class Base > > def self.pid_fn > > File.join(WorkingDirectory, "log", "#{name}.pid") > > end > > > def self.daemonize > > Controller.daemonize(self) > > end > > end > > > module PidFile > > def self.store(daemon, pid) > > File.open(daemon.pid_fn, ''w'') {|f| f << pid} > > end > > > def self.recall(daemon) > > IO.read(daemon.pid_fn).to_i rescue nil > > end > > end > > > module Controller > > def self.daemonize(daemon) > > case !ARGV.empty? && ARGV[0] > > when ''start'' > > start(daemon) > > when ''stop'' > > stop(daemon) > > when ''restart'' > > stop(daemon) > > start(daemon) > > else > > puts "Invalid command. Please specify start, stop or restart." > > exit > > end > > end > > > def self.start(daemon) > > fork do > > Process.setsid > > exit if fork > > PidFile.store(daemon, Process.pid) > > Dir.chdir WorkingDirectory > > File.umask 0000 > > STDIN.reopen "/dev/null" > > #STDOUT.reopen "/dev/null", "a" > > STDERR.reopen STDOUT > > trap("TERM") {daemon.stop; exit} > > daemon.start > > end > > end > > > def self.stop(daemon) > > if !File.file?(daemon.pid_fn) > > puts "Pid file not found. Is the daemon started?" > > exit > > end > > pid = PidFile.recall(daemon) > > FileUtils.rm(daemon.pid_fn) > > pid && Process.kill("TERM", pid) > > end > > end > > end
I tried this, but it still does not work. It seems that I always have the following error whenever I require rails environment. And the weird thing is that if I start the daemon first time using "RAILS_ENV=development lib/daemons/mydaemon_ctl start" it works fine. And then i stop the daemon using "RAILS_ENV=development lib/daemons/ mydaemon_ctl stop", it stops. But there is memory leak, possibly because of the following exceptions. If I start the daemon again, it does not work anymore. Please help. The following is the error message. All of the uninitialized constants in the following error message are actually my Model classes. # Logfile created on May 25, 2009 by / *** below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally *** #<NameError: uninitialized constant CorporationReferralCategory> *** below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions *** #<NoMemoryError: failed to allocate memory> #<SystemStackError: stack level too deep> #<fatal: exception reentered> #<NameError: uninitialized constant Calculator> #<Errno::ENOENT: No such file or directory - /workspace/CA/BETA_3/ EconveyancePro/log/sphinx_index_daemon.rb.pid> #<Errno::EEXIST: File exists - /workspace/CA/BETA_3/EconveyancePro/db/ sphinx/development> #<Errno::EEXIST: File exists - /workspace/CA/BETA_3/EconveyancePro/db/ sphinx/development> #<Errno::EEXIST: File exists - /workspace/CA/BETA_3/EconveyancePro/db/ sphinx/development> #<Errno::EEXIST: File exists - /workspace/CA/BETA_3/EconveyancePro/db/ sphinx/development> #<Errno::EEXIST: File exists - /workspace/CA/BETA_3/EconveyancePro/db/ sphinx/development> #<Errno::EEXIST: File exists - /workspace/CA/BETA_3/EconveyancePro/db/ sphinx/development> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant Realtor> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant CticInterestQuestion> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant IndividualApplicationSetting> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant DocJob> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant TrustAccount> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant UtilitySearchFee> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant FctAccumulationAmount> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant Processor> #<TypeError: can''t dup TrueClass> #<NameError: uninitialized constant CorporationReferralCategory> On Apr 24, 10:04 am, gaveeno <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''ve found a solution that works for me -- not sure if it''s the > "right" way to fix this but it does the job. > > I changed the directory settings in config/daemons.yml to: > dir_mode: normal > dir: > > (used to be dir_mode: script and dir: ../../log) > > I then expanded some of the paths used in mailer_ctl, and inserted > some code to populate the "dir" option (which was blank in the YML > file) with the expanded path of the log directory if the "dir_mode" > option is set to "normal". > > #!/usr/bin/env ruby > > require ''rubygems'' > require "daemons" > require ''yaml'' > require ''erb'' > > ######## > #EXPAND PATH > ######## > file_name = File.expand_path(File.dirname(__FILE__) + "/../../vendor/ > rails/activesupport/lib/active_support.rb") > > if(File.exists?(file_name)) > require file_name > else > rails_version = File.new(File.dirname(__FILE__) + "/../../config/ > environment.rb").read.scan(/^ *RAILS_GEM_VERSION.*=.*[''|"](.*)[''|"]/) > [0].to_s > gem ''activesupport'', rails_version > require ''active_support'' > end > > ######## > #EXPAND PATH > ######## > options = YAML.load( > ERB.new( > IO.read( > File.expand_path(File.dirname(__FILE__) + "/../../config/ > daemons.yml") > )).result).with_indifferent_access > options[:dir_mode] = options[:dir_mode].to_sym > > ######## > #EXPAND PATH OF LOG DIRECTORY > ######## > if options[:dir_mode] == :normal > options[:dir] = File.expand_path(File.dirname(__FILE__) + "/../../ > log/") > end > > Daemons.run File.dirname(__FILE__) + ''/mailer.rb'', options > > On Apr 24, 9:01 am, gaveeno <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I forgot to mention that I checked and the file mentioned in the error > > is in that directory. Not sure why Rails thinks it''s missing... > > > On Apr 23, 7:22 pm, gaveeno <gavin.to...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > I followed the instructions athttp://railscasts.com/episodes/129-custom-daemon > > > for creating adaemon. Simple enough, right? Wrong... > > > > For some reason, I keep getting an error when running thedaemoneven > > > if I remove all mycustomcode from the generated code. Anybody know > > > what I''m doing wrong?? > > > > The error and thedaemoncode is athttp://pastie.org/456601aswell > > > as below: > > > > ************************ > > > The error (from log/mailer.rb.log): > > > ************************ > > > > # Logfile created on Thu Apr 23 19:06:31 -0700 2009 by / > > > *** below you find the most recent exception thrown, this will be > > > likely (but not certainly) the exception that made the application > > > exit abnormally *** > > > #<Errno::ENOENT: No such file or directory - ./lib/daemons/../../ > > > vendor/rails/activesupport/lib/active_support/locale/en.yml> > > > *** below you find all exception objects found in memory, some of them > > > may have been thrown in your application, others may just be in memory > > > because they are standard exceptions *** > > > #<NoMemoryError: failed to allocate memory> > > > #<SystemStackError: stack level too deep> > > > #<fatal: exception reentered> > > > #<Errno::ENOENT: No such file or directory - ./lib/daemons/../../ > > > vendor/rails/activesupport/lib/active_support/locale/en.yml> > > > > ************************ > > > lib/daemons/mailer.rb > > > ************************ > > > #!/usr/bin/env ruby > > > > ENV["RAILS_ENV"] ||= "production" > > > > require File.dirname(__FILE__) + "/../../config/environment" > > > > $running = true > > > Signal.trap("TERM") do > > > $running = false > > > end > > > > while($running) do > > > > # I removed mycustomcode to test whether the error was a result of > > > what I > > > # was trying to do, and the error still appears. The rest of the > > > code here > > > # was created by the daemon_generator plugin. > > > > sleep 10 > > > end > > > > ************************ > > > lib/daemons/mailer_ctl > > > Again, nocustomcode here > > > ************************ > > > > #!/usr/bin/env ruby > > > require ''rubygems'' > > > require "daemons" > > > require ''yaml'' > > > require ''erb'' > > > > file_name = File.dirname(__FILE__) + "/../../vendor/rails/ > > > activesupport/lib/active_support.rb" > > > > if(File.exists?(file_name)) > > > require file_name > > > else > > > rails_version = File.new(File.dirname(__FILE__)+ "/../../config/ > > > environment.rb").read.scan(/^ *RAILS_GEM_VERSION.*=.*[''|"](.*)[''|"]/) > > > [0].to_s > > > > gem ''activesupport'', rails_version > > > require ''active_support'' > > > end > > > > options = YAML.load( > > > ERB.new( > > > IO.read( > > > File.dirname(__FILE__) + "/../../config/daemons.yml" > > > )).result).with_indifferent_access > > > options[:dir_mode] = options[:dir_mode].to_sym > > > > Daemons.run File.dirname(__FILE__) + ''/mailer.rb'', options > > > > ************************ > > > lib/daemon.rb > > > ************************ > > > > # Taken fromhttp://snippets.dzone.com/posts/show/2265 > > > > require ''fileutils'' > > > > moduleDaemon > > > WorkingDirectory = File.join(File.dirname(__FILE__), ''..'') > > > > class Base > > > def self.pid_fn > > > File.join(WorkingDirectory, "log", "#{name}.pid") > > > end > > > > def self.daemonize > > > Controller.daemonize(self) > > > end > > > end > > > > module PidFile > > > def self.store(daemon, pid) > > > File.open(daemon.pid_fn, ''w'') {|f| f << pid} > > > end > > > > def self.recall(daemon) > > > IO.read(daemon.pid_fn).to_i rescue nil > > > end > > > end > > > > module Controller > > > def self.daemonize(daemon) > > > case !ARGV.empty? && ARGV[0] > > > when ''start'' > > > start(daemon) > > > when ''stop'' > > > stop(daemon) > > > when ''restart'' > > > stop(daemon) > > > start(daemon) > > > else > > > puts "Invalid command. Please specify start, stop or restart." > > > exit > > > end > > > end > > > > def self.start(daemon) > > > fork do > > > Process.setsid > > > exit if fork > > > PidFile.store(daemon, Process.pid) > > > Dir.chdir WorkingDirectory > > > File.umask 0000 > > > STDIN.reopen "/dev/null" > > > #STDOUT.reopen "/dev/null", "a" > > > STDERR.reopen STDOUT > > > trap("TERM") {daemon.stop; exit} > > > daemon.start > > > end > > > end > > > > def self.stop(daemon) > > > if !File.file?(daemon.pid_fn) > > > puts "Pid file not found. Is thedaemonstarted?" > > > exit > > > end > > > pid = PidFile.recall(daemon) > > > FileUtils.rm(daemon.pid_fn) > > > pid && Process.kill("TERM", pid) > > > end > > > end > > > end