Merge lp:~james-w/python-timeline-django/start-end-request into lp:python-timeline-django

Proposed by James Westby
Status: Merged
Approved by: Michael Nelson
Approved revision: 21
Merged at revision: 20
Proposed branch: lp:~james-w/python-timeline-django/start-end-request
Merge into: lp:python-timeline-django
Diff against target: 41 lines (+20/-1)
2 files modified
timeline_django/tests/test_wsgi.py (+19/-0)
timeline_django/wsgi.py (+1/-1)
To merge this branch: bzr merge lp:~james-w/python-timeline-django/start-end-request
Reviewer Review Type Date Requested Status
Michael Nelson (community) Approve
Review via email: mp+183552@code.launchpad.net

Commit message

Save the environ before sending the wsgi_request_started signal.

Code that listens to the wsgi_request_started signal may want to use the
environ, but instead of using the one passed to the signal, it may
call get_environ() to get the saved version. That has to be the
current request's environ, not any previous request, so save the environ
before triggering the signal.

Description of the change

Hi,

This fixes the oopses we are currently seeing on sso. They are caused
because a stale timeline from the previous request is sometimes being used.

The commit message has a fuller explanation of the problem and the fix.

Thanks,

James

To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote :

LGTM - it's not clear to me how this results in the OverlappingActionError - but makes sense (and I trust you :-) ).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'timeline_django/tests/test_wsgi.py'
--- timeline_django/tests/test_wsgi.py 2013-08-26 02:13:01 +0000
+++ timeline_django/tests/test_wsgi.py 2013-09-03 00:27:53 +0000
@@ -74,3 +74,22 @@
74 pass74 pass
75 wrapped_app(environ, start_response)75 wrapped_app(environ, start_response)
76 self.assertEqual([environ], called_environs)76 self.assertEqual([environ], called_environs)
77
78 def test_sends_wsgi_request_started_after_saving_environ(self):
79 # Code that listens to the wsgi_request_started signal may
80 # want to use the environ, but instead of using the one
81 # passed to the signal, they may call get_environ() to get
82 # the saved version. That has to be the current request's
83 # environ, not any previous request.
84 signal = self.patch_signal('wsgi_request_started')
85 called_environs = []
86 def capture_signal(sender, environ, signal=None):
87 # Save the environ that we get from get_environ() at
88 # the time of the signal
89 called_environs.append(wsgi.get_environ())
90 signal.connect(capture_signal)
91 wrapped_app = wsgi.make_app(lambda environ, start_response: None)
92 environ = object()
93 wrapped_app(environ, None)
94 # Check that the saved environ matches the one passed to the app
95 self.assertEqual([environ], called_environs)
7796
=== modified file 'timeline_django/wsgi.py'
--- timeline_django/wsgi.py 2013-08-26 02:13:01 +0000
+++ timeline_django/wsgi.py 2013-09-03 00:27:53 +0000
@@ -45,9 +45,9 @@
45 :return: A WSGI app wrapping application.45 :return: A WSGI app wrapping application.
46 """46 """
47 def save_environ(environ, start_response):47 def save_environ(environ, start_response):
48 _thread_local.environ = environ
48 signals.wsgi_request_started.send(sender=save_environ,49 signals.wsgi_request_started.send(sender=save_environ,
49 environ=environ)50 environ=environ)
50 _thread_local.environ = environ
51 def signalled_start_response(*args, **kwargs):51 def signalled_start_response(*args, **kwargs):
52 signals.wsgi_response_started.send(sender=save_environ,52 signals.wsgi_response_started.send(sender=save_environ,
53 environ=environ)53 environ=environ)

Subscribers

People subscribed via source and target branches