Rail 5 swap ActionDispatch::Reloader with a custom reloader

Rail 5 swap ActionDispatch::Reloader with a custom reloader

我们有一个用例,用于在本地开发时安装模拟引擎来处理会话,其中自定义会话中间件在请求通过时通过 Net::http 请求调用模拟引擎。

当代码发生变化时,触发重新加载器,here调用ActiveSupport::Dependencies开始卸载。然后将请求传递到我们的自定义会话中间件并触发 http 请求。 然而,由于 http 请求调用了一个可装载的引擎,它再次考虑相同的中间件并且重新加载器再次卸载所有依赖项,这导致第一次重新加载超时。所以目标是能够跳过第二次请求的重新加载。

我将以下代码添加到 ActionDispatch::Reloader here,它完全符合我的要求。

class Reloader < Executor
  def initialize(app, executor)
    super(app, executor)
  end

  def call(env)
    request = ActionDispatch::Request.new(env)
    return @app.call(env) if skip_request?(request)
    super(env)
  end

  def skip_request?(request)        
    request.path_info.start_with?('/session')
  end
end

然后我想让这个清洁器把它完全拉出到一个模块中,然后像这样从初始化程序中进行交换

app.config.middleware.swap(::ActionDispatch::Reloader, MyModule::CustomReloaderMiddleware)

这是模块

require 'action_dispatch'

module MyModule
  class CustomReloaderMiddleware < ActionDispatch::Executor
    def initialize(app, executor)
      @app, @executor = app, executor
    end

    def call(env)
      request = ActionDispatch::Request.new(env)
      return @app.call(env) if skip_request?(request)
      super(env)
    end

    def skip_request?(request)
      request.path_info.start_with?('/session')
    end
  end
end

但我 运行 遇到了几个问题。

Uncaught exception: wrong number of arguments (given 1, expected 2)initializeMyModule,当我启动服务器时。然后我尝试了以下

#1

def initialize(app, executor = nil)
  @app, @executor = app, executor
end

#2

def initialize(app, executor = nil)
  @app, @executor = app, ActiveSupport::Reloader
end

他们都正确启动了服务,我看到请求通过这个中间件,但它没有重新加载代码。所以我想知道用自定义重新加载器交换 ActionDispatch::Reloader 的正确方法是什么?

您需要将中间件的附加参数传递给 swap 调用:

app.config.middleware.swap(::ActionDispatch::Reloader, MyModule::CustomReloaderMiddleware, app.reloader)

这与 ActionDispatch::Reloaderfirst added 时给出的参数相同——它是应用程序的重新加载器,它是 AS::Reloader 的更具体配置的子类(所以你走对了路).