solid_queue icon indicating copy to clipboard operation
solid_queue copied to clipboard

Starting Puma with solid_queue plugin in Render.com fails

Open megatux opened this issue 5 months ago • 3 comments

Seems like it happens when forking. Contents of my puma.rb

threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
port ENV.fetch("PORT", 3000)

# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart

# Specify the PID file. Defaults to tmp/pids/server.pid in development.
# In other environments, only set the PID file if requested.
pidfile ENV["PIDFILE"] if ENV["PIDFILE"]

if ENV["SOLID_QUEUE_IN_PUMA"]
  puts "---- DEBUG MSG: Solid Queue inside Puma ----"
  plugin :solid_queue
end
==> Running 'bundle exec puma -t 5:5 -p ${PORT:-3000} -e ${RACK_ENV:-development}'
---- DEBUG MSG: Solid Queue inside Puma ----
[117] Puma starting in cluster mode...
[117] * Puma version: 6.6.0 ("Return to Forever")
[117] * Ruby version: ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [x86_64-linux]
[117] *  Min threads: 5
[117] *  Max threads: 5
[117] *  Environment: production
[117] *   Master PID: 117
[117] *      Workers: 2
[117] *     Restarts: (✔) hot (✖) phased
[117] * Preloading application
[117] ! Unable to load application: TypeError: no implicit conversion from nil to integer
bundler: failed to load command: puma (/opt/render/project/.gems/bin/puma)
/opt/render/project/.gems/ruby/3.4.0/gems/solid_queue-1.2.1/lib/puma/plugin/solid_queue.rb:27:in 'Process.waitpid': no implicit conversion from nil to integer (TypeError)
      Process.waitpid(solid_queue_pid, Process::WNOHANG)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	from /opt/render/project/.gems/ruby/3.4.0/gems/solid_queue-1.2.1/lib/puma/plugin/solid_queue.rb:27:in 'stop_solid_queue'
	from /opt/render/project/.gems/ruby/3.4.0/gems/solid_queue-1.2.1/lib/puma/plugin/solid_queue.rb:21:in 'block in start'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb:17:in 'block in Puma::Events#fire'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb:17:in 'Array#each'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb:17:in 'Puma::Events#fire'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb:54:in 'Puma::Events#fire_on_stopped!'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher.rb:280:in 'Puma::Launcher#do_graceful_stop'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher.rb:445:in 'block in Puma::Launcher#setup_signals'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/timestamp.rb:143:in 'Kernel#block_given?'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/timestamp.rb:143:in 'TZInfo::Timestamp.for'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/transition_rule.rb:39:in 'TZInfo::TransitionRule#at'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/annual_rules.rb:66:in 'TZInfo::AnnualRules#apply_rule'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/annual_rules.rb:51:in 'TZInfo::AnnualRules#transitions'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:326:in 'block in TZInfo::DataSources::ZoneinfoReader#apply_rules_with_transitions'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:326:in 'Integer#upto'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:326:in 'Enumerator#each'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:326:in 'Enumerable#flat_map'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:326:in 'TZInfo::DataSources::ZoneinfoReader#apply_rules_with_transitions'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:475:in 'TZInfo::DataSources::ZoneinfoReader#parse'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:42:in 'block in TZInfo::DataSources::ZoneinfoReader#read'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:42:in 'IO.open'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_reader.rb:42:in 'TZInfo::DataSources::ZoneinfoReader#read'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_sources/zoneinfo_data_source.rb:311:in 'TZInfo::DataSources::ZoneinfoDataSource#load_timezone_info'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_source.rb:256:in 'block in TZInfo::DataSource#eager_load!'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_source.rb:256:in 'Array#each'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo/data_source.rb:256:in 'TZInfo::DataSource#eager_load!'
	from /opt/render/project/.gems/ruby/3.4.0/gems/tzinfo-2.0.6/lib/tzinfo.rb:15:in 'TZInfo.eager_load!'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/application/finisher.rb:81:in 'Array#each'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/application/finisher.rb:81:in 'block in <module:Finisher>'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/initializable.rb:32:in 'BasicObject#instance_exec'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/initializable.rb:32:in 'Rails::Initializable::Initializer#run'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/initializable.rb:61:in 'block in Rails::Initializable#run_initializers'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:231:in 'block in TSort.tsort_each'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:353:in 'block (2 levels) in TSort.each_strongly_connected_component'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:434:in 'TSort.each_strongly_connected_component_from'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:352:in 'block in TSort.each_strongly_connected_component'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:350:in 'Rails::Initializable::Collection#each'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:350:in 'Method#call'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:350:in 'TSort.each_strongly_connected_component'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:229:in 'TSort.tsort_each'
	from /opt/render/project/rubies/ruby-3.4.3/lib/ruby/3.4.0/tsort.rb:208:in 'TSort#tsort_each'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/initializable.rb:60:in 'Rails::Initializable#run_initializers'
	from /opt/render/project/.gems/ruby/3.4.0/gems/railties-8.0.2/lib/rails/application.rb:440:in 'Rails::Application#initialize!'
	from /opt/render/project/src/config/environment.rb:5:in '<top (required)>'
	from config.ru:3:in 'Kernel#require_relative'
	from config.ru:3:in 'block (2 levels) in <top (required)>'
	from /opt/render/project/.gems/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb:108:in 'Kernel#eval'
	from /opt/render/project/.gems/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb:108:in 'Rack::Builder.new_from_string'
	from /opt/render/project/.gems/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb:97:in 'Rack::Builder.load_file'
	from /opt/render/project/.gems/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb:67:in 'Rack::Builder.parse_file'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/configuration.rb:386:in 'Puma::Configuration#load_rackup'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/configuration.rb:297:in 'Puma::Configuration#app'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/runner.rb:169:in 'Puma::Runner#load_and_bind'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster.rb:373:in 'Puma::Cluster#run'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher.rb:203:in 'Puma::Launcher#run'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cli.rb:75:in 'Puma::CLI#run'
	from /opt/render/project/.gems/ruby/3.4.0/gems/puma-6.6.0/bin/puma:10:in '<top (required)>'
	from /opt/render/project/.gems/bin/puma:27:in 'Kernel#load'
	from /opt/render/project/.gems/bin/puma:27:in '<top (required)>'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/cli/exec.rb:59:in 'Kernel.load'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/cli/exec.rb:59:in 'Bundler::CLI::Exec#kernel_load'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/cli/exec.rb:23:in 'Bundler::CLI::Exec#run'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/cli.rb:452:in 'Bundler::CLI#exec'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/vendor/thor/lib/thor/command.rb:28:in 'Bundler::Thor::Command#run'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in 'Bundler::Thor::Invocation#invoke_command'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/vendor/thor/lib/thor.rb:538:in 'Bundler::Thor.dispatch'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/cli.rb:35:in 'Bundler::CLI.dispatch'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/vendor/thor/lib/thor/base.rb:584:in 'Bundler::Thor::Base::ClassMethods#start'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/cli.rb:29:in 'Bundler::CLI.start'
	from /opt/render/project/.gems/gems/bundler-2.6.7/exe/bundle:28:in 'block in <top (required)>'
	from /opt/render/project/.gems/gems/bundler-2.6.7/lib/bundler/friendly_errors.rb:117:in 'Bundler.with_friendly_errors'
	from /opt/render/project/.gems/gems/bundler-2.6.7/exe/bundle:20:in '<top (required)>'
	from /opt/render/project/.gems/bin/bundle:108:in 'Kernel#load'
	from /opt/render/project/.gems/bin/bundle:108:in '<main>'

megatux avatar Jul 31 '25 19:07 megatux

@megatux I've tried to reproduce your issue.

Steps:

  1. rails new <proj-name> (I use Rails 8.0.2 and Ruby 3.4.5)
  2. Update puma.rb with:
# Run the Solid Queue supervisor inside of Puma for single-server deployments
if ENV["SOLID_QUEUE_IN_PUMA"]
  puts "---- DEBUG MSG: Solid Queue inside Puma ----"
  plugin :solid_queue
end
  1. Pushed to GitHub repo (https://github.com/ivnhk/solid-queue-test)
  2. Added env var SOLID_QUEUE_IN_PUMA set to true on Render 5.Triggered the deployment
  3. Observed the logs

My logs:

2025-08-13T18:06:42.431847229Z => Booting Puma
2025-08-13T18:06:42.43187682Z => Rails 8.0.2 application starting in production 
2025-08-13T18:06:42.431880069Z => Run `bin/rails server --help` for more startup options
2025-08-13T18:06:42.748206141Z ==> Your service is live 🎉

2025-08-13T18:06:49.437796357Z ---- DEBUG MSG: Solid Queue inside Puma ----
2025-08-13T18:06:49.437832787Z [37] Puma starting in cluster mode...
2025-08-13T18:06:49.437836808Z [37] * Puma version: 6.6.1 ("Return to Forever")
2025-08-13T18:06:49.437841378Z [37] * Ruby version: ruby 3.4.5 (2025-07-16 revision 20cda200d3) +YJIT +PRISM [x86_64-linux]
2025-08-13T18:06:49.437845628Z [37] *  Min threads: 3
2025-08-13T18:06:49.437849248Z [37] *  Max threads: 3
2025-08-13T18:06:49.437853718Z [37] *  Environment: production
2025-08-13T18:06:49.437857078Z [37] *   Master PID: 37
2025-08-13T18:06:49.437859198Z [37] *      Workers: 2
2025-08-13T18:06:49.437873079Z [37] *     Restarts: (✔) hot (✖) phased (✖) refork
2025-08-13T18:06:49.437875429Z [37] * Preloading application
2025-08-13T18:06:49.439212734Z [37] * Listening on http://0.0.0.0:3000
2025-08-13T18:06:49.439428299Z [37] Use Ctrl-C to stop
2025-08-13T18:06:49.536110778Z [37] - Worker 0 (PID: 47) booted in 0.01s, phase: 0
2025-08-13T18:06:49.628325431Z [37] - Worker 1 (PID: 56) booted in 0.09s, phase: 0

So far, so good.

ivnhk avatar Aug 13 '25 18:08 ivnhk

I can try to:

  • downgrade the Ruby version for this project
  • set threads to 5

and see what happens

Yet my question is: do you have any additional config/info that may help me to reproduce the issue?

upd. None of those were a problem

ivnhk avatar Aug 13 '25 18:08 ivnhk

You are right, fork did return nil. The only case I can think of when this can happen is that fork failed. Unfortunately, I don't know when this happens.

Do you have any idea when fork returns nil?

ivnhk avatar Aug 13 '25 19:08 ivnhk