]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
LBaaS: handle NotFound exceptions in update_status callback
authorOleg Bondarev <obondarev@mirantis.com>
Mon, 16 Dec 2013 09:17:48 +0000 (13:17 +0400)
committerThomas Goirand <thomas@goirand.fr>
Thu, 13 Mar 2014 07:20:11 +0000 (15:20 +0800)
LBaaS agent may send update_status requests to server on objects
which were already deleted from db: this is due to creating and
deleting objects with a high rate (like tempest API tests do).
As a result errors and stacktraces appear in server and agent logs.
The proposed solution is to catch NotFound exceptions and print a warning.

Change-Id: I4446b678893d0bda578ad7ccdf3f109cb1c91b4d
Closes-Bug: #1260682

neutron/services/loadbalancer/drivers/haproxy/plugin_driver.py
neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_plugin_driver.py

index a269af306ca54d1106cc808bbb35f072f2bd84c7..495014180af1d695e9f14a123eed14006c81f9f8 100644 (file)
@@ -162,12 +162,20 @@ class LoadBalancerCallbacks(object):
         }
         if obj_type not in model_mapping:
             raise q_exc.Invalid(_('Unknown object type: %s') % obj_type)
-        elif obj_type == 'health_monitor':
-            self.plugin.update_pool_health_monitor(
-                context, obj_id['monitor_id'], obj_id['pool_id'], status)
-        else:
-            self.plugin.update_status(
-                context, model_mapping[obj_type], obj_id, status)
+        try:
+            if obj_type == 'health_monitor':
+                self.plugin.update_pool_health_monitor(
+                    context, obj_id['monitor_id'], obj_id['pool_id'], status)
+            else:
+                self.plugin.update_status(
+                    context, model_mapping[obj_type], obj_id, status)
+        except q_exc.NotFound:
+            # update_status may come from agent on an object which was
+            # already deleted from db with other request
+            LOG.warning(_('Cannot update status: %(obj_type)s %(obj_id)s '
+                          'not found in the DB, it was probably deleted '
+                          'concurrently'),
+                        {'obj_type': obj_type, 'obj_id': obj_id})
 
     def pool_destroyed(self, context, pool_id=None):
         """Agent confirmation hook that a pool has been destroyed.
index 821c8cc6d422e39fd2b2a08716dd1e17e2c5c59e..2db78f34e9aa7f62a90b02f6a3ba9e16a805fd9a 100644 (file)
@@ -25,6 +25,7 @@ from neutron.common import exceptions
 from neutron import context
 from neutron.db.loadbalancer import loadbalancer_db as ldb
 from neutron.db import servicetype_db as st_db
+from neutron.extensions import loadbalancer
 from neutron.extensions import portbindings
 from neutron import manager
 from neutron.openstack.common import uuidutils
@@ -398,6 +399,15 @@ class TestLoadBalancerCallbacks(TestLoadBalancerPluginBase):
             p = self.plugin_instance.get_pool(ctx, pool_id)
             self.assertEqual('ACTIVE', p['status'])
 
+    def test_update_status_pool_deleted_already(self):
+        with mock.patch.object(plugin_driver, 'LOG') as mock_log:
+            pool_id = 'deleted_pool'
+            ctx = context.get_admin_context()
+            self.assertRaises(loadbalancer.PoolNotFound,
+                              self.plugin_instance.get_pool, ctx, pool_id)
+            self.callbacks.update_status(ctx, 'pool', pool_id, 'ACTIVE')
+            self.assertTrue(mock_log.warning.called)
+
     def test_update_status_health_monitor(self):
         with contextlib.nested(
             self.pool(),