Refactor sqlerror tween to add support for pyramid_retry
hopefully this doesn't break anything else..
This commit is contained in:
parent
56392ccdd0
commit
528c0f9622
9
setup.py
9
setup.py
|
@ -64,13 +64,6 @@ requires = [
|
||||||
#
|
#
|
||||||
# package # low high
|
# package # low high
|
||||||
|
|
||||||
# TODO: Pyramid 1.9 looks like it breaks us..? playing it safe for now..
|
|
||||||
'pyramid<1.9', # 1.3b2 1.8.3
|
|
||||||
|
|
||||||
# apparently 2.0 removes the retry support, in which case we then need
|
|
||||||
# pyramid_retry .. but that requires pyramid 1.9 ...
|
|
||||||
'pyramid_tm<2.0', # 0.3 1.1.1
|
|
||||||
|
|
||||||
# TODO: why do we need to cap this? breaks tailbone.db zope stuff somehow
|
# TODO: why do we need to cap this? breaks tailbone.db zope stuff somehow
|
||||||
'zope.sqlalchemy<1.0', # 0.7 0.7.7
|
'zope.sqlalchemy<1.0', # 0.7 0.7.7
|
||||||
|
|
||||||
|
@ -82,10 +75,12 @@ requires = [
|
||||||
'paginate', # 0.5.6
|
'paginate', # 0.5.6
|
||||||
'paginate_sqlalchemy', # 0.2.0
|
'paginate_sqlalchemy', # 0.2.0
|
||||||
'passlib', # 1.7.1
|
'passlib', # 1.7.1
|
||||||
|
'pyramid', # 1.3b2
|
||||||
'pyramid_beaker>=0.6', # 0.6.1
|
'pyramid_beaker>=0.6', # 0.6.1
|
||||||
'pyramid_deform', # 0.2
|
'pyramid_deform', # 0.2
|
||||||
'pyramid_exclog', # 0.6
|
'pyramid_exclog', # 0.6
|
||||||
'pyramid_mako', # 1.0.2
|
'pyramid_mako', # 1.0.2
|
||||||
|
'pyramid_tm', # 0.3
|
||||||
'rattail[db,bouncer]', # 0.5.0
|
'rattail[db,bouncer]', # 0.5.0
|
||||||
'six', # 1.10.0
|
'six', # 1.10.0
|
||||||
'transaction', # 1.2.0
|
'transaction', # 1.2.0
|
||||||
|
|
|
@ -29,32 +29,46 @@ from __future__ import unicode_literals, absolute_import
|
||||||
import six
|
import six
|
||||||
from sqlalchemy.exc import OperationalError
|
from sqlalchemy.exc import OperationalError
|
||||||
|
|
||||||
from transaction.interfaces import TransientError
|
|
||||||
|
|
||||||
|
|
||||||
def sqlerror_tween_factory(handler, registry):
|
def sqlerror_tween_factory(handler, registry):
|
||||||
"""
|
"""
|
||||||
Produces a tween which will convert ``sqlalchemy.exc.OperationalError``
|
Produces a tween which will convert ``sqlalchemy.exc.OperationalError``
|
||||||
instances (caused by database server restart) into a retryable
|
instances (caused by database server restart) into a retryable error
|
||||||
``transaction.interfaces.TransientError`` instance, so that a second
|
instance, so that a second attempt may be made to connect to the database
|
||||||
attempt may be made to connect to the database before really giving up.
|
before really giving up.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
This tween alone is not enough to cause the transaction to be retried;
|
This tween alone is not enough to cause the transaction to be retried;
|
||||||
it only marks the error as being *retryable*. If you wish more than one
|
it only marks the error as being *retryable*. If you wish more than one
|
||||||
attempt to be made, you must define the ``tm.attempts`` setting within
|
attempt to be made, you must define the ``retry.attempts`` (or
|
||||||
your Pyramid app configuration. For more info see `Retrying`_.
|
``tm.attempts`` if running pyramid<1.9) setting within your Pyramid app
|
||||||
|
configuration. For more info see `Retrying`_.
|
||||||
|
|
||||||
.. _Retrying: http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/#retrying
|
.. _Retrying: http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/#retrying
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def sqlerror_tween(request):
|
def sqlerror_tween(request):
|
||||||
|
try:
|
||||||
|
from pyramid_retry import mark_error_retryable
|
||||||
|
except ImportError:
|
||||||
|
mark_error_retryable = None
|
||||||
|
from transaction.interfaces import TransientError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = handler(request)
|
response = handler(request)
|
||||||
except OperationalError as error:
|
except OperationalError as error:
|
||||||
|
|
||||||
|
# if connection is invalid, allow retry
|
||||||
if error.connection_invalidated:
|
if error.connection_invalidated:
|
||||||
raise TransientError(six.text_type(error))
|
if mark_error_retryable:
|
||||||
|
mark_error_retryable(error)
|
||||||
|
raise error
|
||||||
|
else:
|
||||||
|
raise TransientError(six.text_type(error))
|
||||||
|
|
||||||
|
# if connection was *not* invalid, raise original error
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
return sqlerror_tween
|
return sqlerror_tween
|
||||||
|
|
Loading…
Reference in a new issue