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
2 changed files with 24 additions and 15 deletions
|
@ -29,32 +29,46 @@ from __future__ import unicode_literals, absolute_import
|
|||
import six
|
||||
from sqlalchemy.exc import OperationalError
|
||||
|
||||
from transaction.interfaces import TransientError
|
||||
|
||||
|
||||
def sqlerror_tween_factory(handler, registry):
|
||||
"""
|
||||
Produces a tween which will convert ``sqlalchemy.exc.OperationalError``
|
||||
instances (caused by database server restart) into a retryable
|
||||
``transaction.interfaces.TransientError`` instance, so that a second
|
||||
attempt may be made to connect to the database before really giving up.
|
||||
instances (caused by database server restart) into a retryable error
|
||||
instance, so that a second attempt may be made to connect to the database
|
||||
before really giving up.
|
||||
|
||||
.. note::
|
||||
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
|
||||
attempt to be made, you must define the ``tm.attempts`` setting within
|
||||
your Pyramid app configuration. For more info see `Retrying`_.
|
||||
attempt to be made, you must define the ``retry.attempts`` (or
|
||||
``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
|
||||
"""
|
||||
|
||||
def sqlerror_tween(request):
|
||||
try:
|
||||
from pyramid_retry import mark_error_retryable
|
||||
except ImportError:
|
||||
mark_error_retryable = None
|
||||
from transaction.interfaces import TransientError
|
||||
|
||||
try:
|
||||
response = handler(request)
|
||||
except OperationalError as error:
|
||||
|
||||
# if connection is invalid, allow retry
|
||||
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
|
||||
|
||||
return response
|
||||
|
||||
return sqlerror_tween
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue