我有一个简单的 Rails 应用程序,它从远程 URL 中为模型的每个实例(我们称之为 A)抓取 JSON。然后,该应用程序在 1st 的关联模型下创建一个新的数据点。我们称此中间模型为 B,数据点模型为 C。还有一个前端让用户以图形/视觉方式浏览此数据。
因此,层次结构是 A 有很多 -> B,而 B 有很多 -> C。我为每个 A 抓取一个 URL,它返回 B 的一些实例,新 C 具有相应 B 的数据。
在尝试测试/扩展此应用程序时,我遇到了一个问题,即 Rails 将停止处理、挂起一段时间,最后抛出“ActiveRecord::ConnectionTimeoutError 无法在 5.000 秒内获得数据库连接”,显然 5 是只是默认值。
我不明白为什么会发生这种情况 1) 没有显式进行数据库调用,2) 日志不显示在它工作时发生的任何后台数据库调用 3) 它有时工作但有时不工作其他。
rails 4 AR 和连接池是怎么回事?!
一些注意事项:
- 一般算法是为每个模型 A 生成一个线程,抓取数据,在内存中创建模型 C 的新实例,最后将所有 C 保存在一个事务中。
- 有时这行得通,有时却行不通,我不知道是什么原因导致它失败。然而,一旦失败,它似乎就会越来越失败。
- 我渴望加载所有模型 A 和 B。
- 我在最后使用一个事务来插入所有新创建的 C 实例。
- 我目前使用 resque 和 resque 调度程序来完成这项工作,但我非常怀疑它们是问题的根源,因为即使我只是执行“rails runner Class.do_work”,它仍然存在
非常感谢任何建议和想法!
最佳答案
我相信我已经找到了这个问题的原因。当您通过
循环关联时model.association.each do |a|
#work here
end
Rails 做了一些“使用”数据库连接的幕后工作。我将 uses 放在引号中,因为在我的例子中,我认为结果实际上是从内存中返回的。我急切地加载了关联,因此数据库从未真正被命中。
将我的 block 包装在
中的初步测试ActiveRecord::Base.connection_pool.with_connection do
#something me doing?
end
似乎已经解决了这个问题。
我通过向打印出的线程错误消息添加回溯来发现这一点。
-----对于那些使用resque的人----
我还必须在我的 resque.rake 文件中添加一些内容才能使其完全按预期工作。
task 'resque:setup' => :environment do
Resque.after_fork do |job|
ActiveRecord::Base.establish_connection
end
end
关于ruby-on-rails - Rails 4 多线程应用程序 - ActiveRecord::ConnectionTimeoutError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22207919/