2014-05-21 24 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