2014-05-21 22 views
2

此问题通过可实施Sidekiq作业的方式处理性能和优化问题。在Sidekiq作业结束之前释放ActiveRecord连接

假设我们有以下的作业工作流

在步骤1闪避执行

# Step 1 
do_things_with_activerecord_db_and_get_some_parameters() 

# Step 2 
step2_perform_an_http_request_with_these_parameters_on_unreliable_server() 

在以下的情况下,一个ActiveRecord连接从池中取出,并且只有在SideKiq的ActiveRecord中间件完成(或失败)工作后才会由SideKiq发布。

由于我们做请求的步骤2中的外部http服务器不可靠,因此http请求可能需要很长时间甚至超时,因此ActiveRecord连接永远都是锁定的,对吗?

所以我的问题是:是否有相关性,实用性和安全调用:

的ActiveRecord :: Base.clear_active_connections!

在步骤1和步骤2之间,这样作业可以自己释放资源并使其可用于其他类似的作业?或者我错过了关于连接池的东西?此方法是否也可以应用于redis连接?

感谢提前!

回答

2

你一定要打电话给clear_active_connections !.

我们在一个使用TorqueBox服务器上的JMS的环境中运行ActiveRecord,为了确保连接被释放,我们必须做类似的事情。

作为一个告诫,如果你产生了一个使用ActiveRecord的线程,你也需要这样做,因为(在ActiveRecord 3.2中肯定)线程ID被用作连接检出过程的一部分。

我们重复使用的模式如下:

def with_connection(&block) 
    ActiveRecord::Base.connection_pool.with_connection do 
    yield block 
    end 
ensure 
    ActiveRecord::Base.clear_active_connections! 
    ActiveRecord::Base.connection.close 
end 

,你可以使用这样的:

with_connection do 
    do_things_with_activerecord_db_and_get_some_parameters() 
end 
+0

使用with_connection是在这里做正确的事情。您的确保块不是必需的。 –

+1

@MikePerham在使用with_connection连续泄露JMS消息处理器中的连接之后,添加了确保块。 – mcfinnigan

+0

非常感谢您对这两个非常明确的答案,这对我来说很有意义。我借此机会感谢并祝贺Mike的杰出框架。 – Ben