tmp_restart是puma自带的插件,其源码如下。主要就是在server start时先记录tmp/restart.txt的mtime,然后每隔2秒检查一次该文件是否有touch过,若有,则重启

Puma::Plugin.create do
  def start(launcher)
    path = File.join("tmp", "restart.txt")

    orig = nil

    # If we can't write to the path, then just don't bother with this plugin
    begin
      File.write(path, "") unless File.exist?(path)
      orig = File.stat(path).mtime
    rescue SystemCallError
      return
    end

    in_background do
      while true
        sleep 2
        begin
          mtime = File.stat(path).mtime
        rescue SystemCallError
          # If the file has disappeared, assume that means don't restart
        else
          if mtime > orig
            launcher.restart
            break
          end
        end
      end
    end
  end
end


in_background就是新建一个线程来执行。

module Puma
  class PluginRegistry
    def add_background(blk)
      @background << blk
    end

    def fire_background
      @background.each do |b|
        Thread.new(&b)
      end
    end
  end

  Plugins = PluginRegistry.new

  class Plugin
    def self.create(&blk)
      name = extract_name(caller)
      cls = Class.new(self)
      cls.class_eval(&blk)
      Plugins.register name, cls
    end

    def in_background(&blk)
      Plugins.add_background blk
    end
  end
end


launcher.restart会导致进程停止获取请求(见lib/puma/server.rb的handle_server和handle_check),并立即返回,使tmp/restart.txt的检查马上break掉