mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-01 05:48:45 +08:00
Pitchfork has been the default web server for some time now. This removes Unicorn entirely to simplify the codebase and unblock future improvements (like Rack 3). Notable changes beyond the straightforward removal: - `Discourse.after_unicorn_worker_fork` → `Discourse.apply_worker_db_variables_overrides`: renamed and wired into pitchfork.conf.rb's `after_worker_fork`. This actually *fixes* per-worker DB variable overrides (`unicorn_worker_db_variables_*`) which were never called under Pitchfork. - `bin/ember-cli`: `--unicorn` flag renamed to `--server` (`-u` kept). - `lib/demon/sidekiq.rb`: removed Unicorn-specific USR1/USR2 signal handlers and `reopen_logs` (called `Unicorn::Util.reopen_logs`), which were already dead code under Pitchfork. Intentionally kept unchanged: - `config/unicorn_launcher` (used by Docker images, separate effort) - `docker_manager` plugin (separate repo) - `UNICORN_*` env vars (renaming deferred) - Rack < 3 constraint (separate PR)
160 lines
4.3 KiB
Ruby
Executable file
160 lines
4.3 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
require "pathname"
|
|
require "open3"
|
|
|
|
RAILS_ROOT = File.expand_path("../../", Pathname.new(__FILE__).realpath)
|
|
PORT = ENV["UNICORN_PORT"] ||= "3000"
|
|
HOSTNAME = ENV["DISCOURSE_HOSTNAME"] ||= "127.0.0.1"
|
|
CUSTOM_ARGS = %w[--try --test --build --server --unicorn -u --forward-host]
|
|
PROXY =
|
|
if ARGV.include?("--try")
|
|
"https://try.discourse.org"
|
|
else
|
|
"http://#{HOSTNAME}:#{PORT}"
|
|
end
|
|
|
|
def process_running?(pid)
|
|
!!Process.kill(0, pid)
|
|
rescue Errno::ESRCH
|
|
false
|
|
end
|
|
|
|
command =
|
|
if ARGV.include?("--test")
|
|
"test"
|
|
elsif ARGV.include?("--build")
|
|
"build"
|
|
else
|
|
"server"
|
|
end
|
|
|
|
class String
|
|
def cyan
|
|
"\e[36m#{self}\e[0m"
|
|
end
|
|
|
|
def red
|
|
"\033[31m#{self}\e[0m"
|
|
end
|
|
end
|
|
|
|
if ARGV.include?("-h") || ARGV.include?("--help")
|
|
puts "ember-cli OPTIONS"
|
|
puts "#{"--try".cyan} To proxy try.discourse.org"
|
|
puts "#{"--test".cyan} To run the test suite"
|
|
puts "#{"--server, -u".cyan} To run a server as well"
|
|
puts "The rest of the arguments are passed to ember server per:", ""
|
|
exec "pnpm ember #{command} --help"
|
|
end
|
|
|
|
args = ["--dir=frontend/discourse", "ember", command] + (ARGV - CUSTOM_ARGS)
|
|
|
|
if !args.include?("test") && !args.include?("build") && !args.include?("--proxy")
|
|
args << "--proxy"
|
|
args << PROXY
|
|
end
|
|
|
|
node_modules_outdated =
|
|
begin
|
|
File.read("node_modules/.pnpm/lock.yaml") != File.read("pnpm-lock.yaml")
|
|
rescue Errno::ENOENT
|
|
true
|
|
end
|
|
|
|
if node_modules_outdated
|
|
puts "[bin/ember-cli] Detected outdated or missing node_modules. Running pnpm install..."
|
|
|
|
if !system "pnpm", "--dir=#{RAILS_ROOT}", "install"
|
|
if !system("command -v pnpm >/dev/null;")
|
|
abort "pnpm is not installed. run `npm install -g pnpm`"
|
|
end
|
|
exit 1
|
|
end
|
|
end
|
|
|
|
pnpm_env = {
|
|
"TERM" => "dumb", # simple output from ember-cli, so we can parse/forward it more easily
|
|
}
|
|
pnpm_env["FORWARD_HOST"] = "true" if ARGV.include?("--forward-host")
|
|
|
|
if ARGV.include?("-u") || ARGV.include?("--server") || ARGV.include?("--unicorn")
|
|
server_env = { "DISCOURSE_PORT" => ENV["DISCOURSE_PORT"] || "4200" }
|
|
|
|
if command == "server" && ENV["CODESPACE_NAME"]
|
|
server_env.merge!(
|
|
{
|
|
"DISCOURSE_PORT" => "443",
|
|
"DISCOURSE_FORCE_HTTPS" => "1",
|
|
"DISCOURSE_FORCE_HOSTNAME" =>
|
|
"#{ENV["CODESPACE_NAME"]}-4200.#{ENV["GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"]}",
|
|
},
|
|
)
|
|
end
|
|
|
|
server_pid = spawn(server_env, "#{__dir__}/pitchfork")
|
|
ember_cli_pid = nil
|
|
sigint_received = false
|
|
|
|
Thread.new do
|
|
Open3.popen2e(pnpm_env, "pnpm", *args.to_a.flatten) do |i, oe, t|
|
|
ember_cli_pid = t.pid
|
|
puts "Ember CLI running on PID: #{ember_cli_pid}"
|
|
oe.each do |line|
|
|
if line.include?("\e[32m200\e") || line.include?("\e[36m304\e[0m") ||
|
|
line.include?("POST /message-bus")
|
|
# skip 200s and 304s and message bus
|
|
else
|
|
puts "[ember-cli] #{line}"
|
|
end
|
|
end
|
|
end
|
|
# Only send TERM to the server if ember exited on its own (not from
|
|
# Ctrl+C). When the user presses Ctrl+C, all processes in the foreground
|
|
# group already received INT directly from the terminal. Sending an
|
|
# additional TERM races with the server's hard shutdown and can cause it
|
|
# to fall back to a slow graceful shutdown, making the process appear
|
|
# stuck for up to 60 seconds.
|
|
if !sigint_received && process_running?(server_pid)
|
|
puts "[bin/ember-cli] ember-cli process stopped. Terminating server."
|
|
Process.kill("TERM", server_pid)
|
|
end
|
|
end
|
|
|
|
int_count = 0
|
|
trap("INT") do
|
|
sigint_received = true
|
|
int_count += 1
|
|
case int_count
|
|
when 1
|
|
# Swallowed to give children time to handle it
|
|
when 2
|
|
puts "\n[bin/ember-cli] Interrupt again to force shutdown..."
|
|
else
|
|
puts "\n[bin/ember-cli] Forcing shutdown..."
|
|
begin
|
|
Process.kill("KILL", server_pid)
|
|
rescue StandardError
|
|
nil
|
|
end
|
|
if ember_cli_pid
|
|
begin
|
|
Process.kill("KILL", ember_cli_pid)
|
|
rescue StandardError
|
|
nil
|
|
end
|
|
end
|
|
exit!(1)
|
|
end
|
|
end
|
|
|
|
Process.wait(server_pid)
|
|
|
|
if ember_cli_pid && process_running?(ember_cli_pid)
|
|
puts "[bin/ember-cli] server process stopped. Terminating ember-cli."
|
|
Process.kill("TERM", ember_cli_pid)
|
|
end
|
|
else
|
|
exec(pnpm_env, "pnpm", *args.to_a.flatten)
|
|
end
|