2013-07-06 54 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进行测试。你应该嘲笑任务并单独测试它。