2011-06-02 68 views
12

Django中间件线程安全吗?我可以做这样的事情,Django中间件线程安全吗?

class ThreadsafeTestMiddleware(object): 

    def process_request(self, request): 
     self.thread_safe_variable = some_dynamic_value_from_request 

    def process_response(self, request, response): 
     # will self.thread_safe_variable always equal to some_dynamic_value_from_request? 

回答

27

为什么不是你的变量绑定请求对象,像这样:

class ThreadsafeTestMiddleware(object): 

    def process_request(self, request): 
     request.thread_safe_variable = some_dynamic_value_from_request 

    def process_response(self, request, response): 
     #... do something with request.thread_safe_variable here ... 
+0

更好的可能是将它绑定到request.session(https://docs.djangoproject.com/en/1.3/topics/http/sessions/)。 – Bryan 2011-06-02 20:51:42

7

不,非常肯定不是。我写这个问题here - 结果是在中间件类中存储状态是一个非常糟糕的主意。

正如Steve指出的,解决方案是将其添加到请求中。

+0

该链接已损坏。这是一个正确的:http://blog.roseman.org.uk/2010/02/01/middleware-post-processing-django-gotcha/ – 2013-01-05 11:20:39

0

如果您在使用多线程守护进程模式下使用mod_wsgi,则这些选项都不起作用。

WSGIDaemonProcess domain.com用户= WWW的数据组= WWW的数据线程= 2

这是棘手,因为它会与django的开发服务器(单,本地线程)的工作,并根据生产得到不可预知的结果在你的线程的一生中。

无论是设置请求属性还是操作会话都是在mod_wsgi下的线程安全。由于process_response将请求作为参数,所以您应该在该函数中执行所有的逻辑。

class ThreadsafeTestMiddleware(object): 

    def process_response(self, request, response): 
     thread_safe_variable = request.some_dynamic_value_from_request 
+0

这是不正确的。您的请求/响应对象不会在线程和/或请求之间共享,因此可以安全使用。 – 2014-01-09 15:18:09

+0

没有为我工作。我遇到了第一个用户的请求数据被设置为线程生命周期并导致问题的情况。 – roktechie 2014-01-09 19:01:16

+0

请求对象是在请求开始时创建的,并且在请求通过所有中间件类并处理并再次通过中间件返回之前不会处理。这与线程无关 - 它是完全相同的,未共享的对象。 – 2014-01-16 20:22:16