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