首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails 4多线程应用程序- ActiveRecord::ConnectionTimeoutError

Rails 4多线程应用程序- ActiveRecord::ConnectionTimeoutError
EN

Stack Overflow用户
提问于 2014-03-05 19:58:16
回答 2查看 780关注 0票数 2

我有一个简单的rails应用程序,它为模型的每个实例从远程URL中抓取JSON (让我们称之为A)。然后,该应用程序在1号相关模型下创建一个新的数据点。让我们称之为中间模型B和数据点模型C。还有一个前端,让用户以图形/可视化的方式浏览这些数据。

因此,层次结构是A有许多-> B,它有许多-> C。我为每个A刮一个URL,它用新的Cs返回B的几个实例,这些新的C都有各自B的数据。

在尝试测试/缩放这个应用程序时,我遇到了一个问题,rails将停止处理,挂起一段时间,最后抛出一个"ActiveRecord::ConnectionTimeoutError无法在5.000秒内获得数据库连接“,这显然是默认的5。

我不明白为什么会发生这样的情况:( 1)没有显式地进行DB调用;( 2)日志不显示在正常DB调用下发生的任何调用(当它确实工作时);( 3)它有时工作,而不是其他。

rails 4AR和连接池是怎么回事?!

几个注意事项:

  1. 一般算法是为每个模型A生成一个线程,刮取数据,在内存中创建模型C的新实例,在结束时将所有C保存在一个事务中。
  2. 有时这是可行的,有时却不行,我不知道是什么原因导致它失败的。然而,一旦失败,它似乎越来越失败。
  3. 我急于装上所有的A型和B型。
  4. 我在末尾使用一个事务来插入所有新创建的C实例。
  5. 我目前使用resque和resque调度程序来完成这项工作,但我非常怀疑它们是问题的根源,因为即使我只执行"rails runner Class.do_work“,问题仍然存在。

任何建议和想法都非常感谢!

EN

回答 2

Stack Overflow用户

发布于 2014-03-18 22:00:25

我相信我已经找到了这个问题的原因。当您循环遍历一个关联时

代码语言:javascript
复制
model.association.each do |a|
   #work here
end

Rails在幕后做了一些“使用”DB连接的工作。我使用引号,因为在我的例子中,我认为结果实际上是从内存中返回的。我急切地加载了关联,因此DB从未真正命中。

包我的块的初步测试

代码语言:javascript
复制
ActiveRecord::Base.connection_pool.with_connection do 
#something me doing?
end

似乎已经解决了这个问题。

我通过向我的线程打印出的错误消息添加了一个反向跟踪来发现这一点。

我还必须在我的resque.rake文件中添加一点,以使它完全按预期工作。

代码语言:javascript
复制
task 'resque:setup' => :environment do 
  Resque.after_fork do |job|
    ActiveRecord::Base.establish_connection
  end
end
票数 1
EN

Stack Overflow用户

发布于 2014-03-05 20:01:43

如果你在用

代码语言:javascript
复制
ActiveRecord::Base.transaction do 

    ... code

end

要在线程中完成更快的事务,请注意这会锁定数据库。我有一个应用程序,它在一个线程中完成了一个非常昂贵的进程,它会锁定DB超过5秒。虽然它会锁定数据库,但速度更快。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22207919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档