Daemon in background mode crashing repeatedly
Opened this issue · 4 comments
Hello,
It seems there is a problem in the 'run_background' method of the rails daemon, the '::Logging' class does not exists
def run_background(command = 'start', options = {})
options = default_options.merge(options)
FileUtils.mkdir_p(options[:pid_dir])
begin
require 'daemons'
rescue LoadError
raise "You need to add gem 'daemons' to your Gemfile if you wish to use it."
end
unless %w(start stop restart run).include?(command)
raise "Command exptected to be 'start', 'stop', 'restart', 'run', was #{command.inspect}"
end
STDOUT.puts("Dynflow Executor: #{command} in progress")
options[:executors_count].times do
daemons_class.run_proc(
options[:process_name],
daemons_options(command, options)
) do |*_args|
begin
::Logging.reopen
run(options[:rails_root], options)
rescue => e
Logger.new(File.join(options[:rails_root], 'log/daemon.log')).error(e.inspect)
STDERR.puts e.message
::Rails.logger.fatal('Failed running Dynflow daemon')
::Rails.logger.fatal(e)
exit 1
end
end
end
end
It causes the daemon to crash unexpectedly and silently as no logs are being emitted (Rails.logger does not log in any files at this point of time due to the daemonizing process)
I do not see the point of this reopen
method maybe just deleting the line would be ok
How are you trying to run it?
In a rake task in my rails app
args[:executors_count].to_i.times do |i|
daemon.run_background('start', {executors_count: 1, process_name: "dynflow_executor_#{i}"})
end
By the way, for Dynflow to work with Rails I had to hack around and do
dynflow_engine = Dynflow::Rails.new
Rails.application.define_singleton_method(:dynflow) { dynflow_engine }
dynflow_engine.require!
Prior to be able to use Dynflow at all with Rails
In Foreman we use the Logging
gem for logging, but in order for logging to work, the file descriptors need to be reopened after a fork. That's why we can't just delete the line. We could however either check if ::Logging
is defined or explicitly require it.
About the hacking part, take a look how it's done in Foreman https://github.com/theforeman/foreman/blob/develop/config/application.rb#L300https://github.com/theforeman/foreman/blob/develop/config/application.rb#L300
Thanks for the example but if I do like you suggest
@dynflow =
if defined?(ForemanTasks)
ForemanTasks.dynflow
else
::Dynflow::Rails.new(nil, ::Foreman::Dynflow::Configuration.new)
end
@dynflow.require!
@dynflow
In the context of a Rails application I got the following error
/Users/gtrgrt/.rvm/gems/ruby-2.6.1/gems/dynflow-1.2.1/lib/dynflow/rails/configuration.rb:84:in 'remote?': undefined method `dynflow' for #<MyProject::Application:0x00007f9f1823eee8> (NoMethodError)
Which is why I had to use the following hack
dynflow_engine = Dynflow::Rails.new(nil, CustomDynflowConfig.new(true))
Rails.application.define_singleton_method(:dynflow) { dynflow_engine }
dynflow_engine.require!
dynflow_engine.initialize!
I'm not sure how you get it working in Foreman