RuntimeError:在 Rack 中的迭代期间无法将新密钥添加到哈希中
Posted
技术标签:
【中文标题】RuntimeError:在 Rack 中的迭代期间无法将新密钥添加到哈希中【英文标题】:RuntimeError: can't add a new key into hash during iteration in Rack 【发布时间】:2018-05-25 21:33:18 【问题描述】:我构建了一个非常小的 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
我了解,当您在迭代该哈希时尝试向该哈希添加新键时会发生此错误。因为@env
是一个哈希,所以它是有道理的。但是:
-
在堆栈跟踪中,我没有发现任何与
@env
上的迭代相关的内容,这是一个简单的 app.call(env)
调用链。
这个错误并不总是发生,而是一两个小时发生一次,所以这对我来说也很奇怪
我无法在本地重现它:我尝试加载具有多个请求命中的服务器,假设这可能是线程安全问题,但在本地它就像一个魅力...
完整的堆栈跟踪仅包含机架中间件,可在此处找到: https://gist.github.com/Nattfodd/e513122400b4115a653ea38d69917a9a
Gemfile.lock: https://gist.github.com/Nattfodd/a9015e9204544302bf3959cec466b715
服务器使用 puma 运行,配置非常简单:只是线程和工作线程的数量:
threads 0, 5
workers 5
我目前的想法是:
其中一个监控 gem 存在错误(sentry-raven、new_relic) concurrent-ruby 有一个错误(我读过一个,但它在 1.0.2 中已修复,而我用于 Puma 的实际版本是 1.0.5) 一些超级愚蠢的东西,我错过了,但我不知道在哪里看,因为控制器的操作包含 3 行代码,并且应用程序配置大多是默认的... 这与配置有关,因为回溯根本不包含控制器...【问题讨论】:
你有想过这个吗?我有同样的问题 是的,原因是newrelic_rpm
最新版本。仍然不知道究竟是什么导致了 newrelic gem 中的这个错误。
感谢您的回复。关于使用哪个版本的新遗物稳定且不会导致此问题的任何建议?
4.6.0 肯定坏了,不能说是 4.7 还是 4.5 还可以——我还没有测试过
一个类似的错误已经间歇性地影响我的生产应用程序 2 年多,在 unicorn 和 puma 上,newrelic_rpm
的版本范围从 v3.16.0.318 到 v4.8.0.341。一个区别是我的堆栈跟踪的顶部位于 aws-sdk
客户端连接池处理程序 (issue) 中,但由于这没有出现任何明显的问题,我越来越怀疑 New Relic 检测是罪魁祸首。我的堆栈跟踪的另一个共同点是它还包括 sinatra + activerecord- 也许这也相关?
【参考方案1】:
你能粘贴完整的堆栈跟踪吗? 我的假设是 set_header 是从迭代 env 的方法中调用的。
【讨论】:
完整堆栈跟踪的链接在我的问题中 - gist.github.com/Nattfodd/e513122400b4115a653ea38d69917a9a以上是关于RuntimeError:在 Rack 中的迭代期间无法将新密钥添加到哈希中的主要内容,如果未能解决你的问题,请参考以下文章
是否有解决方案绕过“无法在迭代期间将新密钥添加到哈希(RuntimeError)”?
递归:如何避免 Python set changed set 在迭代 RuntimeError 期间
通过 DataLoader (PyTorch) 迭代:RuntimeError: 标量类型 unsigned char 的预期对象但序列元素 9 的标量类型浮点数