2013-07-06 55 views
1

我有以更快返回在創建單獨線程一些對象多線程的Django應用程序。創建的對象僅用於跟蹤用戶已完成的操作,而且不會對時間敏感。Django的線程和測試

使用看起來像這樣的視圖功能:

def foo(request): 
    #... do important computation... 
    bar(x, y, z) 
    return HttpResponse() 

一切工作在這裏很好,但是當我改變它看起來像這一點,並使用線程:

def foo(request): 
    #... do important computation... 
    thread = Thread(target=bar, args=(x, y, z)) 
    thread.start() 
    if testing_mode: 
     thread.join() 
    return HttpResponse() 

第二個版本失敗。這一切都是使用TransactionTestCase和mySQL完成的。

任何想法?

+0

什麼工作者線程? –

+0

我已經更新了這個問題。它更清楚嗎?基本思想是,如果bar()在測試數據庫中創建一個對象,那麼它不在第二個代碼中,但它在第一個代碼中。 – jmetz

+0

你應該檢查你的假設。如果考慮到Django的數據庫連接的工作方式,我會非常驚訝,在線程中創建多個項目比以串行方式更快。 –

回答

1

的分流請求使用線程也不是那麼好主意。有很多陷阱,而且沒有什麼好處。存在的主要問題(和你的問題涉及到這些)是:

  • 在Django每個線程使用單獨的數據庫連接,因此:
    • 你交易的寬鬆好處
    • 您必須手動關閉線程
    • 連接
    • ,如果你不關閉連接在正確的方式線程(這是很難做好事),你將有數百個開放連接到你的數據庫中,這將帶給你
    • 你有測試問題的問題,因爲測試框架做了一些t在DB連接裏克斯,並不能做到這一點從螺紋連接
  • 翻譯框架並不在線程工作
  • 你線程,如果WSGI服務器決定重新加載過早死​​亡,但沒有要求處理
  • Django的錯誤處理不會對線程工作

正確的方式做這將是:

  • 優化你的代碼以服務請求更快或
  • 使用任務系統,如芹菜或RQ卸載工作到背景(這有上面的一些問題,但更簡單)。

PS。不要嘗試安裝Celery或RQ進行測試。你應該嘲笑任務並單獨測試它。