App Engine / Django - 交错多个请求干扰GAE-Sessions

时间:2013-01-05 00:32:11

标签: django google-app-engine session gae-sessions

我正在使用Django在App Engine上运行python应用程序。此外,我正在使用名为gae-sessions的会话管理库。如果threadsafe设置为"no",则没有问题,但当threadsafe设置为"yes"时,我偶尔会发现会话丢失的问题。

我看到的问题是,当启用了treading时,GAE-Sessions中间件中的多个请求会偶尔交错。

gae-sessions库中,有一个名为_tls的变量,它是一个threading.local()变量。当用户向网站发出http请求时,首先运行名为process_request()的函数,然后为当前页面生成一堆自定义html生成,然后运行名为process_response()的函数。记住状态在process_request“线程安全”变量中的process_response_tls之间。我可以通过打印_tls值(例如_tls)来检查"<thread._local object at 0xfc2e8de0>"变量的唯一性。

我偶尔会看到的是GAE-Sessions中间件中似乎是一个单独的线程(由于它们与thread_local对象具有相同的内存位置而推断为单个线程,并由事实上,来自一个请求的数据似乎覆盖了来自另一个请求的数据),多个http请求正在交错。鉴于User1和User2同时发出请求,我目睹了以下执行顺序:

User1 -> `process_request` is executed on thread A
User2 -> `process_request` is executed on thread A
User2 -> `process_response` is executed on thread A
User1 -> `process_response` is executed on thread A

鉴于上述情况,User2会话踩踏一些内部变量并导致User1的会话丢失。

所以,我的问题如下: 1)这是中间件中不同请求的交错预期在App-Engine / Django / Python中的行为吗? (或者我完全困惑,这里还有其他事情发生) 2)这种交错发生在什么级别(App-Engine / Django / Python)?

看到这种行为我感到非常惊讶,因此有兴趣了解这里发生的原因/发生的事情。

1 个答案:

答案 0 :(得分:2)

我发现以下链接有助于了解正在发生的事情:

假设我正确地理解了一切,上面发生的原因如下:

1)当Django运行时,它在包含Django Middleware的父(公共)线程中运行大部分基本功能。

2)个别请求在子线程中运行,子线程可以与父线程交互。

上述结果是请求(子线程)确实可以在中间件中交错 - 这是设计的(只运行Django的单个副本,中间件可以节省内存,更高效等) 。 [请参阅我在本答案中链接的第一篇文章,以快速描述线程和子/父进程如何交互]

关于GAE-Sessions - 我们正在检查的线程对于不同的请求是相同的,因为它是父线程(对所有子/请求都是通用的),而不是到每次输入中间件时我们正在查看的子线程

GAE-Sessions将状态数据存储在中间件中,由于父线程(Django + Middlware)线程内的子线程可能交错,因此可能会被不同的请求覆盖。我应用于GAE-Sessions的修复是将所有状态数据存储在请求对象上,而不是在middlware中。

修复:以前对响应处理函数的可写引用存储在DjangoSessionMiddlware对象中self.response_handlers - 我已将其作为request.response_handlers移动到请求对象。我还删除了_tls变量,并将其包含的数据移动到request对象中。