2

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

我看到的问题是,当启用踩踏时,多个请求偶尔会在 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)?

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

4

1 回答 1

2

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

假设我正确理解了所有内容,发生上述情况的原因如下:

1) When Django is running, it runs most of the base functionality in a parent (common) thread that includes the Django Middleware.

2) Individual requests are run in child threads which can interact with the parent thread.

The result of the above is that requests (child threads) can indeed be interleaved within the Middleware - and this is by design (only running a single copy of Django and the Middleware would save memory, be more efficient, etc.). [see the first article that I linked to in this answer for a quick description of how threading and child/parent processes interact]

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

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

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

于 2013-01-07T11:56:43.963 回答