I found the following links to be helpful in understanding what is happening:
- http://blog.notdot.net/2011/10/Migrating-to-Python-2-7-part-1-Threadsafe
- Is Django middleware thread safe?
- http://blog.roseman.org.uk/2010/02/01/middleware-post-processing-django-gotcha/
Assuming that I am understanding everything correctly, the reason that the above happened is the following:
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]
With respect to GAE-Sessions
- the thread that we were examining was the same for different requests, given that it was the parent thread (common for all children/requests), as opposed to the child threads that we were looking at each time that the middleware was entered.
GAE-Sessions
was storing state data in the middleware, which could be over-written by different requests, given the possible interleaving of the child threads within the parent (Django + Middlware) thread. The fix that I applied to GAE-Sessions
was to store all state data on the request object, as opposed to within the middlware.
Fixes: previously a writable reference to response handler functions was stored in the DjangoSessionMiddlware
object as self.response_handlers
- which I have moved to the request object as request.response_handlers
. I also removed the _tls
variable, and moved data that it contained into the request
object.