discourse/bin/unicorn
Martin Brennan 1dd8daef45
DEV: Extract unicorn server PID when ArgumentError raised (#36649)
When the rails server is already running, attempting to start
it again was giving an ArgumentError and outputting the backtrace.
When you are working locally, all you want here is the PID so you
can kill it.

I altered the error message to this in this case:

```
Unicorn is already running!

kill -9 150044 to stop the existing unicorn master process, then try again.
```

So you can easily copy and paste the command to stop the existing
server.

The old error:

<img width="1711" height="243" alt="image"
src="https://github.com/user-attachments/assets/18d5b25b-5da9-45b0-941e-6ee353423cf3"
/>
2025-12-15 09:56:04 +10:00

100 lines
2.5 KiB
Ruby
Executable file

#!/usr/bin/env ruby
# frozen_string_literal: true
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
STDERR.puts <<~MESSAGE if defined?(Bundler)
WARNING: Using `bundle exec` to start the server is unnecessary, and will make startup slower. Use `bin/rails s` or `bin/unicorn`.
MESSAGE
require "rubygems"
require "bundler/setup"
require "fileutils"
dev_mode = false
# in development do some fussing around, to automate config
if !ARGV.include?("-E") && !ARGV.include?("--env") &&
(%w[development test].include?(ENV["RAILS_ENV"]) || !ENV["RAILS_ENV"])
dev_mode = true
ARGV.push("-N")
if !ARGV.include?("-c") && !ARGV.include?("--config-file")
ARGV.push("-c")
ARGV.push(File.expand_path("../../config/unicorn.conf.rb", Pathname.new(__FILE__).realpath))
end
# we do not want to listen on 2 ports, so lets fix it
if (idx = ARGV.index("-p")) && (port = ARGV[idx + 1].to_i) > 0
ENV["UNICORN_PORT"] ||= port.to_s
end
ENV["UNICORN_PORT"] ||= "9292"
if ARGV.delete("-x")
puts "Running without sidekiq"
ENV["UNICORN_SIDEKIQS"] = "0"
end
ENV["UNICORN_SIDEKIQS"] ||= "1"
end
if ARGV.include?("--help")
fork { load Gem.bin_path("unicorn", "unicorn") }
Process.wait
puts "Extra Discourse Options:"
puts " -x run without sidekiq"
exit
end
# this dev_mode hackery enables the following to be used to restart unicorn:
#
# pkill -USR2 -f 'ruby bin/unicorn'
#
# This is handy if you want to bind a key to restarting unicorn in dev
if dev_mode
UNICORN_DEV_SUPERVISOR_PID = Process.pid
restart = true
while restart
restart = false
pid =
fork do
begin
load Gem.bin_path("unicorn", "unicorn")
rescue ArgumentError => err
if (err.message =~ /Already running on PID/)
puts "\n"
puts "Unicorn is already running!\n"
pid = err.message[/PID:(\d+)/, 1]&.to_i
puts "\n"
puts "kill -9 #{pid} to stop the existing unicorn master process, then try again."
else
raise err
end
end
end
done = false
Signal.trap("INT") do
# wait for parent to be done
end
Signal.trap("USR2") do
Process.kill("QUIT", pid)
puts "RESTARTING UNICORN"
restart = true
end
Signal.trap("TERM") { Process.kill("TERM", pid) }
while !done
sleep 1
done = Process.waitpid(pid, Process::WNOHANG)
end
end
else
load Gem.bin_path("unicorn", "unicorn")
end