[Repoze-checkins] r1101 - in repoze.retry/trunk: . repoze/retry
Chris McDonough
chrism at agendaless.com
Wed Jun 18 12:35:30 EDT 2008
Author: Chris McDonough <chrism at agendaless.com>
Date: Wed Jun 18 12:35:29 2008
New Revision: 1101
Log:
Seek wsgi.input back to zero before retrying a request due to a
conflict error.
Modified:
repoze.retry/trunk/CHANGES.txt
repoze.retry/trunk/repoze/retry/__init__.py
repoze.retry/trunk/repoze/retry/tests.py
repoze.retry/trunk/setup.py
Modified: repoze.retry/trunk/CHANGES.txt
==============================================================================
--- repoze.retry/trunk/CHANGES.txt (original)
+++ repoze.retry/trunk/CHANGES.txt Wed Jun 18 12:35:29 2008
@@ -1,3 +1,8 @@
+0.9.1 (2008-06-18)
+
+ Seek wsgi.input back to zero before retrying a request due to a
+ conflict error.
+
0.9 (2008-06-15)
Fixed concurrency bug whereby a response from one request might be
Modified: repoze.retry/trunk/repoze/retry/__init__.py
==============================================================================
--- repoze.retry/trunk/repoze/retry/__init__.py (original)
+++ repoze.retry/trunk/repoze/retry/__init__.py Wed Jun 18 12:35:29 2008
@@ -1,6 +1,8 @@
# repoze retry-on-conflict-error behavior
-import traceback
import itertools
+import os
+import traceback
+from tempfile import TemporaryFile
try:
from ZODB.POSException import ConflictError
@@ -33,6 +35,24 @@
def __call__(self, environ, start_response):
catch_response = []
written = []
+ original_wsgi_input = environ.get('wsgi.input')
+ new_wsgi_input = None
+
+ if original_wsgi_input is not None:
+ cl = environ.get('CONTENT_LENGTH', '0')
+ cl = int(cl)
+ new_wsgi_input = environ['wsgi.input'] = TemporaryFile('w+b')
+ rest = cl
+ chunksize = 1<<20
+ while rest:
+ if rest <= chunksize:
+ chunk = original_wsgi_input.read(rest)
+ rest = 0
+ else:
+ chunk = original_wsgi_input.read(chunksize)
+ rest = rest - chunksize
+ new_wsgi_input.write(chunk)
+ new_wsgi_input.seek(0)
def replace_start_response(status, headers, exc_info=None):
catch_response[:] = [status, headers, exc_info]
@@ -49,6 +69,8 @@
errors.write('repoze.retry retrying, count = %s\n' % i)
traceback.print_exc(environ['wsgi.errors'])
if i < self.tries:
+ if new_wsgi_input is not None:
+ new_wsgi_input.seek(0)
continue
if catch_response:
start_response(*catch_response)
Modified: repoze.retry/trunk/repoze/retry/tests.py
==============================================================================
--- repoze.retry/trunk/repoze/retry/tests.py (original)
+++ repoze.retry/trunk/repoze/retry/tests.py Wed Jun 18 12:35:29 2008
@@ -90,6 +90,33 @@
self.assertEqual(list(result), ['hello'])
self.assertEqual(app2.called, 1)
+ def test_wsgi_input_seeked_to_zero_on_conflict_withcontentlen(self):
+ application = DummyApplication(conflicts=3, call_start_response=True)
+ retry = self._makeOne(application, tries=4,
+ retryable=(self.ConflictError,))
+ env = self._makeEnv()
+ data = 'x' * 1000
+ env['CONTENT_LENGTH'] = str(len(data))
+ from StringIO import StringIO
+ env['wsgi.input'] = StringIO(data)
+ result = retry(env, self._dummy_start_response)
+ self.assertEqual(application.called, 3)
+ self.failIf(isinstance(env['wsgi.input'], StringIO))
+ self.assertEqual(application.wsgi_input, data)
+
+ def test_wsgi_input_seeked_to_zero_on_conflict_nocontentlen(self):
+ application = DummyApplication(conflicts=3, call_start_response=True)
+ retry = self._makeOne(application, tries=4,
+ retryable=(self.ConflictError,))
+ env = self._makeEnv()
+ data = 'x' * 1000
+ from StringIO import StringIO
+ env['wsgi.input'] = StringIO(data)
+ result = retry(env, self._dummy_start_response)
+ self.assertEqual(application.called, 3)
+ self.failIf(isinstance(env['wsgi.input'], StringIO))
+ self.assertEqual(application.wsgi_input, '')
+
class WSGIConformanceTests(RetryTests):
def setUp(self):
@@ -183,6 +210,7 @@
if exception is None:
exception = self.ConflictError
self.exception = exception
+ self.wsgi_input = ''
def __call__(self, environ, start_response):
if self.call_start_response:
@@ -190,6 +218,8 @@
if self.called < self.conflicts:
self.called += 1
raise self.exception
+ if environ.get('wsgi.input'):
+ self.wsgi_input = environ['wsgi.input'].read()
if self.call_start_response:
return ['hello']
# Dead chicken (see above)
Modified: repoze.retry/trunk/setup.py
==============================================================================
--- repoze.retry/trunk/setup.py (original)
+++ repoze.retry/trunk/setup.py Wed Jun 18 12:35:29 2008
@@ -1,4 +1,4 @@
-__version__ = '0.9'
+__version__ = '0.9.1'
import os
from setuptools import setup, find_packages
More information about the Repoze-checkins
mailing list