From d9f3e46633b4a776d9c24a4e6e8ed61790ae790f Mon Sep 17 00:00:00 2001 From: Ann Kamyshnikova Date: Wed, 24 Dec 2014 14:46:27 +0300 Subject: [PATCH] Catch StaleDataError in update_device_down For some reason sometimes at the same time for the same port delete_port and update_device_down commands have been executed. This arise StaleDataError in update_device_down. In other situations these commands are executed one after another and the error doesn't appear. This errors does not show anything broken, but to avoid confusion it will be skipped. Closes-bug: #1405379 Change-Id: I4e5a3d1f1866b9cfba44d3cb7ccc5b2dee1d9633 --- neutron/plugins/ml2/rpc.py | 11 ++++++++--- neutron/tests/unit/ml2/test_rpcapi.py | 7 +++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/neutron/plugins/ml2/rpc.py b/neutron/plugins/ml2/rpc.py index 6efa6dabd..a612ed6a1 100644 --- a/neutron/plugins/ml2/rpc.py +++ b/neutron/plugins/ml2/rpc.py @@ -14,6 +14,7 @@ # under the License. from oslo import messaging +from sqlalchemy.orm import exc from neutron.agent import securitygroups_rpc as sg_rpc from neutron.api.rpc.handlers import dvr_rpc @@ -135,9 +136,13 @@ class RpcCallbacks(type_tunnel.TunnelRpcCallbackMixin): return {'device': device, 'exists': port_exists} - port_exists = bool(plugin.update_port_status(rpc_context, port_id, - q_const.PORT_STATUS_DOWN, - host)) + try: + port_exists = bool(plugin.update_port_status( + rpc_context, port_id, q_const.PORT_STATUS_DOWN, host)) + except exc.StaleDataError: + port_exists = False + LOG.debug("delete_port and update_device_down are being executed " + "concurrently. Ignoring StaleDataError.") return {'device': device, 'exists': port_exists} diff --git a/neutron/tests/unit/ml2/test_rpcapi.py b/neutron/tests/unit/ml2/test_rpcapi.py index 2acf8dd1c..8ed1c9c0f 100644 --- a/neutron/tests/unit/ml2/test_rpcapi.py +++ b/neutron/tests/unit/ml2/test_rpcapi.py @@ -22,6 +22,7 @@ import contextlib import mock from oslo_context import context as oslo_context +from sqlalchemy.orm import exc from neutron.agent import rpc as agent_rpc from neutron.common import constants @@ -162,6 +163,12 @@ class RpcCallbacksTestCase(base.BaseTestCase): 'fake_context', 'fake_port_id', constants.PORT_STATUS_DOWN, 'fake_host') + def test_update_device_down_call_update_port_status_failed(self): + self.plugin.update_port_status.side_effect = exc.StaleDataError + self.assertEqual({'device': 'fake_device', 'exists': False}, + self.callbacks.update_device_down( + 'fake_context', device='fake_device')) + class RpcApiTestCase(base.BaseTestCase): -- 2.45.2