ruby-on-rails - Rails 4 多线程应用程序 - ActiveRecord::ConnectionTimeoutError

标签 ruby-on-rails database multithreading activerecord

我有一个简单的 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 和连接池是怎么回事?!

一些注意事项:

  1. 一般算法是为每个模型 A 生成一个线程,抓取数据,在内存中创建模型 C 的新实例,最后将所有 C 保存在一个事务中。
  2. 有时这行得通,有时却行不通,我不知道是什么原因导致它失败。然而,一旦失败,它似乎就会越来越失败。
  3. 我渴望加载所有模型 A 和 B。
  4. 我在最后使用一个事务来插入所有新创建的 C 实例。
  5. 我目前使用 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/

相关文章:

php - Bootstrap - 如何水平对齐 foreach 内的卡片?

mysql - 如何为 MySQL 中的每个新连接自动调用查询?

xml - Postgres : Importing huge XML files

c# - 如何在 .net 中找到当前线程的最大堆栈大小?

.net - 这是什么错误? Net.HttpWebRequest.SetAndOrProcessResponse 中的 System.Net.InternalException

ruby-on-rails - Rails 3 完整的错误消息格式

mysql - 如何将 GET 参数从自定义日期格式转换为数据库日期格式?

ruby-on-rails - 使用 guard-zeus 时如何修复 guard 的这种失真输出?

ruby-on-rails - 使用 Prawn 生成的 PDF 中右侧缩进的文本

c# - WinForms 中的部分类