Retry port status update on StaleDataError

During update_port_status, a port may be concurrently updated/deleted
by another process, which will result in a StaleDataError being
thrown. In the event it was an update, we want to retry to make sure
the port status is set to the desired state so third parties like Nova
get notified.

This patch uses the oslo_db wrap_db_retry decorator after converting
the StaleDataError into a RetryRequest that the decorator can catch.

Closes-Bug: #1465407
Change-Id: I0a9230d30f435ec3d48f033136e85c40ad489ef9
This commit is contained in:
Kevin Benton 2015-06-15 23:10:09 -07:00
parent 4e77442d52
commit 3c72832c8b
2 changed files with 24 additions and 1 deletions

View File

@ -14,10 +14,13 @@
# under the License.
import contextlib
import six
from oslo_config import cfg
from oslo_db import exception as os_db_exception
from oslo_db.sqlalchemy import session
from sqlalchemy import exc
from sqlalchemy import orm
_FACADE = None
@ -64,3 +67,21 @@ def autonested_transaction(sess):
finally:
with session_context as tx:
yield tx
class convert_db_exception_to_retry(object):
"""Converts other types of DB exceptions into RetryRequests."""
def __init__(self, stale_data=False):
self.to_catch = ()
if stale_data:
self.to_catch += (orm.exc.StaleDataError, )
def __call__(self, f):
@six.wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except self.to_catch as e:
raise os_db_exception.RetryRequest(e)
return wrapper

View File

@ -1376,7 +1376,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
return self._bind_port_if_needed(port_context)
@oslo_db_api.wrap_db_retry(max_retries=db_api.MAX_RETRIES,
retry_on_deadlock=True)
retry_on_deadlock=True,
retry_on_request=True)
@db_api.convert_db_exception_to_retry(stale_data=True)
def update_port_status(self, context, port_id, status, host=None,
network=None):
"""