← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~ricardokirkner/python-oops-wsgi/close-iterable into lp:python-oops-wsgi

 

Ricardo Kirkner has proposed merging lp:~ricardokirkner/python-oops-wsgi/close-iterable into lp:python-oops-wsgi.

Commit message:
fix generator_tracker to behave properly according to WSGI standard

according to http://blog.dscpl.com.au/2012/10/obligations-for-calling-close-on.html
any iterable returned by a WSGI application needs to have .close() called on it

Since django 1.5 this causes connections to be left open as "IDLE in transaction"
when the iterator is not closed

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~ricardokirkner/python-oops-wsgi/close-iterable/+merge/165192
-- 
https://code.launchpad.net/~ricardokirkner/python-oops-wsgi/close-iterable/+merge/165192
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~ricardokirkner/python-oops-wsgi/close-iterable into lp:python-oops-wsgi.
=== modified file 'oops_wsgi/middleware.py'
--- oops_wsgi/middleware.py	2012-01-25 02:29:32 +0000
+++ oops_wsgi/middleware.py	2013-05-22 16:03:30 +0000
@@ -87,7 +87,7 @@
         the key determines the name given in the OOPS context. If None is passed
         the default_map_environ is used. Pass {} in to entirely disable mapping.
     :param tracker: A factory function to create a tracker. Trackers are used
-        to allow variations on the WSGI environment to still use oops_wsgi. 
+        to allow variations on the WSGI environment to still use oops_wsgi.
         See generator_tracker for the reference tracker used in regular WSGI
         environments. generator_tracker is used by default or when
         tracker=None.
@@ -250,3 +250,6 @@
     except Exception:
         exc_info = sys.exc_info()
         yield on_error(exc_info)
+    finally:
+        if hasattr(app_body, 'close'):
+            app_body.close()

=== modified file 'oops_wsgi/tests/test_middleware.py'
--- oops_wsgi/tests/test_middleware.py	2012-01-25 03:00:02 +0000
+++ oops_wsgi/tests/test_middleware.py	2013-05-22 16:03:30 +0000
@@ -630,3 +630,14 @@
         self.assertThat(lambda:tracker.next(), raises(ValueError('fail')))
         self.assertEqual(['on exception foo'], self.calls)
 
+    def test_closes_iterator(self):
+        class mock_iterator(list):
+            def close(self):
+                self.close_called = True
+
+        mock_app_body = mock_iterator()
+        tracker = generator_tracker(
+            self.on_first_bytes, self.on_finish, None, mock_app_body)
+        for result in tracker:
+            pass
+        self.assertTrue(mock_app_body.close_called)


Follow ups