我们有一个用例,用于在本地开发时安装模拟引擎来处理会话,其中自定义会话中间件在请求到达时通过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)
中的initialize
中为 MyModule
。然后我尝试了以下
#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的正确方法是什么?
答案 0 :(得分:1)
您需要将中间件的其他参数传递给swap
调用:
app.config.middleware.swap(::ActionDispatch::Reloader, MyModule::CustomReloaderMiddleware, app.reloader)
与ActionDispatch::Reloader
为first added时给出的参数相同-它是应用程序的重载器,它是AS :: Reloader的更具体配置的子类(因此您处在正确的轨道上)。 / p>