RuntimeError:在Rack中迭代期间无法将新键添加到哈希中

nat*_*odd 11 rack ruby-on-rails sinatra puma

我构建了一个非常小的Rails 5.1.4(Ruby 2.3.1)应用程序.一旦我将其部署到生产环境中,我就会不时收到此特定错误:

RuntimeError: can't add a new key into hash during iteration

指向这里:

# rack/request.rb, line 67
def set_header(name, v)
  @env[name] = v
end
Run Code Online (Sandbox Code Playgroud)

我理解,当您尝试在迭代该哈希时向哈希添加新密钥时,会发生此错误.既然@env是哈希,那就有意义了.但:

  1. 在堆栈跟踪中,我发现没有任何与迭代相关的内容@env,它是一个简单的死链接app.call(env).
  2. 这个错误并不总是发生,但每小时或两次只发生一次,所以这对我来说也是非常奇怪的
  3. 我无法在本地重现它:我尝试加载具有多个请求命中的服务器,假设这可能是线程安全问题,但在本地它就像一个魅力......

完整的堆栈跟踪只包含机架中间件,可以在这里找到:https: //gist.github.com/Nattfodd/e513122400b4115a653ea38d69917a9a

Gemfile.lock:https://gist.github.com/Nattfodd/a9015e9204544302bf3959cec466b715

服务器运行时使用puma,配置非常简单:只是线程和工作量:

threads 0, 5
workers 5
Run Code Online (Sandbox Code Playgroud)

我目前的想法是:

  • 监控宝石之一有一个bug(sentry-raven,new_relic)
  • concurrent-ruby有一个bug(我读过一个,但它在1.0.2中得到修复,而我用于Puma的实际版本是1.0.5)
  • 一些超级愚蠢的东西,我错过了,但我不知道在哪里看,因为控制器的动作包含3行代码,应用程序配置主要是默认的......
  • 这是配置相关的东西,因为回溯根本不包含控制器......

小智 -1

你能粘贴完整的堆栈跟踪吗?我的假设是 set_header 是从迭代环境的方法中调用的。