我正在一个现有的 Rails 2 站点上工作,该站点具有最近更新到 Ruby 1.9.2 和 mysql2 gem 的大型代码库。我注意到这个设置允许非阻塞的数据库查询;你可以做client.query(sql, :async => true)
,然后再调用client.async_result
,它会阻塞直到查询完成。
在我看来,我们可以通过让所有ActiveRecord
返回集合的查询拒绝阻塞,直到在集合上调用方法来提高性能。例如
@widgets = Widget.find(:all, :conditions=> conditions) #sends the query
do_some_stuff_that_doesn't_require_widgets
@widgets.each do #if the query hasn't completed yet, wait until it does, then populate @widgets with the result. Iterate through @widgets
...
这可以通过猴子补丁Base::find
及其相关方法来创建一个新的数据库客户端,异步发送查询,然后立即返回一个 Delegator 或其他代理对象,当任何方法被调用时,调用client.async_result
,实例化结果使用ActiveRecord
, 并将方法委托给它。 ActiveRecord
关联代理对象已经以类似的方式实现 ORM。
但是,我找不到任何这样做的人,而且在任何版本的 Rails 中似乎都不是一个选项。我已经尝试自己实现它并且它在控制台中工作(只要我附加; 1
到调用所有内容的行,这样to_s
就不会在结果中调用它)。但它似乎与其他各种魔法发生碰撞并产生各种问题。
那么,出于某种我没有想到的原因,这是一个坏主意吗?如果没有,为什么它不是ActiveRecord
已经工作的方式?有没有一种干净的方法来实现它?