Commit 9a7a13bf authored by Hanno Schlichting's avatar Hanno Schlichting

Add direct support for ConflictError and TransientError retry logic.

This avoids the `repoze.retry` dependency for WSGIPublisher.
parent 683d6ce9
...@@ -16,6 +16,9 @@ Bugs Fixed ...@@ -16,6 +16,9 @@ Bugs Fixed
Features Added Features Added
++++++++++++++ ++++++++++++++
- Add support for ConflictError and TransientError retry logic directly
into WSGIPublisher.
- Add support for raising HTTPOK and HTTPRedirection exceptions and - Add support for raising HTTPOK and HTTPRedirection exceptions and
have them result in successful transactions. have them result in successful transactions.
......
...@@ -26,7 +26,6 @@ five.globalrequest==1.0 ...@@ -26,7 +26,6 @@ five.globalrequest==1.0
mechanize==0.2.5 mechanize==0.2.5
persistent==4.2.1 persistent==4.2.1
pytz==2016.6.1 pytz==2016.6.1
repoze.retry==1.4
six==1.10.0 six==1.10.0
sourcecodegen==0.6.14 sourcecodegen==0.6.14
transaction==1.6.1 transaction==1.6.1
......
...@@ -62,7 +62,6 @@ setup( ...@@ -62,7 +62,6 @@ setup(
'ZConfig >= 2.9.2', 'ZConfig >= 2.9.2',
'ZODB', 'ZODB',
'five.globalrequest', 'five.globalrequest',
'repoze.retry',
'setuptools', 'setuptools',
'six', 'six',
'sourcecodegen', 'sourcecodegen',
......
...@@ -21,11 +21,13 @@ import time ...@@ -21,11 +21,13 @@ import time
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
import transaction import transaction
from transaction.interfaces import TransientError
from zExceptions import ( from zExceptions import (
HTTPOk, HTTPOk,
HTTPRedirection, HTTPRedirection,
Unauthorized, Unauthorized,
) )
from ZODB.POSException import ConflictError
from zope.event import notify from zope.event import notify
from zope.security.management import newInteraction, endInteraction from zope.security.management import newInteraction, endInteraction
from zope.publisher.skinnable import setDefaultSkin from zope.publisher.skinnable import setDefaultSkin
...@@ -197,7 +199,7 @@ def transaction_pubevents(request, tm=transaction.manager): ...@@ -197,7 +199,7 @@ def transaction_pubevents(request, tm=transaction.manager):
tm.begin() tm.begin()
notify(pubevents.PubStart(request)) notify(pubevents.PubStart(request))
try: try:
yield tm yield None
except (HTTPOk, HTTPRedirection) as exc: except (HTTPOk, HTTPRedirection) as exc:
ok_exception = exc ok_exception = exc
...@@ -259,28 +261,11 @@ def publish(request, module_info): ...@@ -259,28 +261,11 @@ def publish(request, module_info):
return response return response
def publish_module(environ, start_response, def _publish_wsgi(request, response, module_info, start_response, stdout,
_publish=publish, # only for testing _publish=publish):
_response=None,
_response_factory=WSGIResponse,
_request=None,
_request_factory=WSGIRequest,
_module_name='Zope2'):
status = 200
with closing(StringIO()) as stdout, closing(StringIO()) as stderr:
response = (_response if _response is not None else
_response_factory(stdout=stdout, stderr=stderr))
response._http_version = environ['SERVER_PROTOCOL'].split('/')[1]
response._server_version = environ.get('SERVER_SOFTWARE')
request = (_request if _request is not None else
_request_factory(environ['wsgi.input'], environ, response))
with closing(request) as request:
try: try:
with transaction_pubevents(request): with transaction_pubevents(request):
response = _publish(request, get_module_info(_module_name)) response = _publish(request, module_info)
except Unauthorized: except Unauthorized:
response._unauthorized() response._unauthorized()
except HTTPRedirection as exc: except HTTPRedirection as exc:
...@@ -299,6 +284,45 @@ def publish_module(environ, start_response, ...@@ -299,6 +284,45 @@ def publish_module(environ, start_response,
# If somebody used response.write, that data will be in the # If somebody used response.write, that data will be in the
# stdout StringIO, so we put that before the body. # stdout StringIO, so we put that before the body.
result = (stdout.getvalue(), response.body) result = (stdout.getvalue(), response.body)
return (response, result)
def publish_module(environ, start_response,
_publish=publish, # only for testing
_response=None,
_response_factory=WSGIResponse,
_request=None,
_request_factory=WSGIRequest,
_module_name='Zope2'):
module_info = get_module_info(_module_name)
result = ()
with closing(StringIO()) as stdout, closing(StringIO()) as stderr:
response = (_response if _response is not None else
_response_factory(stdout=stdout, stderr=stderr))
response._http_version = environ['SERVER_PROTOCOL'].split('/')[1]
response._server_version = environ.get('SERVER_SOFTWARE')
request = (_request if _request is not None else
_request_factory(environ['wsgi.input'], environ, response))
for i in range(getattr(request, 'retry_max_count', 3) + 1):
try:
response, result = _publish_wsgi(
request, response,
module_info, start_response,
stdout, _publish=_publish)
break
except (ConflictError, TransientError) as exc:
if request.supports_retry():
new_request = request.retry()
request.close()
request = new_request
response = new_request.response
else:
raise
finally:
request.close()
for func in response.after_list: for func in response.after_list:
func() func()
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
############################################################################## ##############################################################################
import unittest import unittest
import transaction
from ZPublisher.WSGIPublisher import get_module_info from ZPublisher.WSGIPublisher import get_module_info
......
...@@ -5,7 +5,6 @@ zope_conf = %(here)s/wsgi.conf ...@@ -5,7 +5,6 @@ zope_conf = %(here)s/wsgi.conf
[pipeline:main] [pipeline:main]
pipeline = pipeline =
egg:Zope2#httpexceptions egg:Zope2#httpexceptions
egg:repoze.retry#retry
zope zope
[server:main] [server:main]
......
...@@ -23,7 +23,6 @@ Products.ZCatalog = 4.0a2 ...@@ -23,7 +23,6 @@ Products.ZCatalog = 4.0a2
Products.ZCTextIndex = 4.0 Products.ZCTextIndex = 4.0
pytz = 2016.6.1 pytz = 2016.6.1
Record = 3.1 Record = 3.1
repoze.retry = 1.4
RestrictedPython = 3.6.0 RestrictedPython = 3.6.0
six = 1.10.0 six = 1.10.0
sourcecodegen = 0.6.14 sourcecodegen = 0.6.14
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment