重新加载 rails 中间件而无需重新启动开发中的服务器 [英] Reloading rails middleware without restarting the server in development

查看:51
本文介绍了重新加载 rails 中间件而无需重新启动开发中的服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有中间件的 rails 4 应用程序,它位于 lib/some/middleware.rb 中,它目前通过一个像这样的初始化程序注入到堆栈中:

I have a rails 4 app with middleware located at lib/some/middleware.rb which is currently injected into the stack though an initializer like so:

MyApp::Application.configure.do |config|
    config.middleware.use 'Some::Middleware'
end

不幸的是,每当我更改某些内容时,我都需要重新启动服务器.如何在开发模式下为每个请求重新加载它?我见过类似的问题,关于使用自动加载或将代码包装在 to_prepare 块中重新加载 lib 代码,但我不确定如何在这种情况下应用它.

Unfortunately, any time I change something I need to restart the server. How can I reload it on each request in development mode? I've seen similar questions about reloading lib code with either autoloading or wrapping code in a to_prepare block but I'm unsure how that could be applied in this scenario.

谢谢,- FJM

更新 #1

如果我尝试删除中间件,然后将其重新添加到 to_prepare 块中,则会收到错误无法修改冻结数组".

If I try to delete the middleware and then re-add it in a to_prepare block I get an error "Can't modify frozen array".

推荐答案

我认为在某些时候 Rails 已经足够聪明,可以在运行时替换中间件代码,但我可能错了.

I thought that at some point Rails was smart enough replacing middleware code at runtime, but I may be wrong.

这就是我想出的办法,绕过 Ruby 类加载疯狂并利用 Rails 类重新加载.

Here is what I came up with, circumventing Ruby class loading craziness and leveraging Rails class reloading.

将中间件添加到堆栈中:

Add the middleware to the stack:

# config/environments/development.rb
[...]
config.middleware.use "SomeMiddleware", "some_additional_paramter"

利用自动重新加载,但要确保正在运行的 rails 实例和已经初始化的中间件对象不断忘记"执行的实际代码:

Make use of auto-reloading, but make sure that the running rails instance and the already initialized middleware object keep "forgetting" about the actual code that is executed:

# app/middlewares/some_middleware.rb
class SomeMiddleware
  def initialize(*args)
    @args = args
  end

  def call(env)
    "#{self.class}::Logic".constantize.new(*@args).call(env)
  end

  class Logic
    def initialize(app, additional)
      @app        = app
      @additional = additional
    end

    def call(env)
      [magic]
      @app.call(env)
    end
  end
end

每个请求的 Rails 自动重新加载都应该获取逻辑上的变化.

Changes in Logic should be picked up by rails auto reloading on each request.

我认为这实际上可能会成为一个有用的宝石!

I think that this actually might become a useful gem!

这篇关于重新加载 rails 中间件而无需重新启动开发中的服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆