首页 > 解决方案 > Rails 5 在重新加载时停止自定义 http 中间件。

问题描述

在 Rails 5 开发模式下,我Net::ReadTimeout(Net::ReadTimeout)在自定义会话中间件中不断收到此错误,该中间件向我的本地模拟自定义会话引擎发出 http 请求。此外,该错误仅在我进行代码更改并且 Rails 呈现错误页面后触发。这非常烦人,并且确实减慢了开发过程,因为我们都必须刷新两次才能看到代码更改的结果。

在跟踪这些中间件中的代码之后,我的自定义会话中间件似乎在重新加载器完成重新加载之前启动了 http 请求。

我想知道我们是否可以停止/停止机架中间件请求,直到重新加载完成为止。

导轨版本:5.1

红宝石版本:2.4.1

我在重新加载器完成重新加载之前和之后放置了以下日志消息

应用程序.rb

ActiveSupport::Reloader.to_run do
  puts 'Reloading'
end

ActiveSupport::Reloader.to_complete do
  puts 'DONE Reloading'
end

custom_session_siddleware.rb

def call(env)
  ...
  puts 'Session Processing'
  http = Net::HTTP.new(uri, port)
  ...
  @app.call(env)
end

我进行代码更改并刷新后的输出

Reloading
Session Processing
DONE Reloading

这是我所有的中间件

use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use RequestStore::Middleware
use ActionDispatch::RemoteIp
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use MyCustomSession::CustomSessionMiddleware

标签: ruby-on-railsruby-on-rails-5

解决方案


如果您的自定义中间件正在向正在运行的 Rack 应用程序发出请求,那么您很容易遇到麻烦。但它可以工作。


当您的初始请求在 Reloader 中时,实际的重新加载已经发生——但这只是unload

卸载后,任何应用程序(或引擎)类在下次访问时都需要再次自动加载......我认为这就是你遇到问题的地方:内部请求需要加载一些东西,但它外部请求处于活动状态时不能这样做。

为了解决这个问题,外部请求需要通知系统它在一个安全的地方供另一个线程/请求加载新代码。具体来说,您Net::HTTP需要@app.call(env).permit_concurrent_loads


推荐阅读