discourse/config/initializers/watch_for_restart.rb

62 lines
1.6 KiB
Ruby

Thread.new do
file = "#{Rails.root}/tmp/restart"
did_exist = nil
old_time = nil
return if $PROGRAM_NAME !~ /thin/
processes = {}
got_new = false
MessageBus.subscribe "/processes" do |msg|
filetime = msg.data["filetime"]
pid = msg.data["pid"]
got_new = processes[pid].nil? || (processes[pid][:filetime] != filetime)
# puts "#{got_new} #{pid}"
processes[pid] = {time: Time.now.to_i, filetime: filetime}
end
while true
exists = File.exists? file
time = File.ctime(file).to_i if exists
if (did_exist != nil && did_exist != exists) ||
(old_time != nil && time != nil && old_time != time)
got_new = false
probably_restarted = []
give_up_time = Time.now.to_i + 60
while Time.now.to_i < give_up_time
candidates = []
processes.each do |pid,data|
if data[:filetime] == old_time && data[:time] > Time.now.to_i - 40
candidates << pid
end
end
candidates = candidates - probably_restarted
break if (candidates.min || $$) >= $$
sleep 1
probably_restarted << candidates.min if got_new
got_new = false
end
Rails.logger.info "attempting to reload #{$$} #{$PROGRAM_NAME} in 3 seconds restarted #{probably_restarted.inspect}"
$shutdown = true
sleep 4
Rails.logger.info "restarting #{$$}"
Process.kill("HUP", $$)
break
end
MessageBus.publish "/processes", {pid: $$, filetime: time}
did_exist = exists
old_time = time
sleep 10
end
end