]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
BSN: Allow concurrent reads to consistency DB
authorKevin Benton <blak111@gmail.com>
Wed, 13 Aug 2014 11:01:50 +0000 (04:01 -0700)
committerKevin Benton <blak111@gmail.com>
Wed, 10 Sep 2014 22:09:03 +0000 (15:09 -0700)
Allow concurrent reads to the consistency DB since the
database lock the block was originally protecting against
is gone.

Closes-Bug: #1357102
Change-Id: I1618b4046e995c796757e723f99288e486683339

neutron/plugins/bigswitch/db/consistency_db.py
neutron/plugins/bigswitch/servermanager.py

index 7f0faff0d392bd739670b64411f942f783d37ef6..3a20c7dfe9574079a136dca742c7517b5c0eec7b 100644 (file)
@@ -14,7 +14,6 @@
 #    under the License.
 import sqlalchemy as sa
 
-from neutron.common import exceptions
 from neutron.db import api as db
 from neutron.db import model_base
 from neutron.openstack.common import log as logging
@@ -22,10 +21,6 @@ from neutron.openstack.common import log as logging
 LOG = logging.getLogger(__name__)
 
 
-class MultipleReadForUpdateCalls(exceptions.NeutronException):
-    message = _("Only one read_for_update call may be made at a time.")
-
-
 class ConsistencyHash(model_base.BASEV2):
     '''
     A simple table to store the latest consistency hash
@@ -41,27 +36,23 @@ class ConsistencyHash(model_base.BASEV2):
 
 class HashHandler(object):
     '''
-    A wrapper object to keep track of the session and hold the SQL
-    lock between the read and the update to prevent other servers
-    from reading the hash during a transaction.
+    A wrapper object to keep track of the session between the read
+    and the update operations.
     '''
     def __init__(self, context=None, hash_id='1'):
         self.hash_id = hash_id
         self.session = db.get_session() if not context else context.session
         self.hash_db_obj = None
-        self.transaction = None
 
     def read_for_update(self):
-        if self.transaction:
-            raise MultipleReadForUpdateCalls()
-        self.transaction = self.session.begin(subtransactions=True)
         # REVISIT(kevinbenton): locking here with the DB is prone to deadlocks
         # in various multi-REST-call scenarios (router intfs, flips, etc).
         # Since it doesn't work in Galera deployments anyway, another sync
         # mechanism will have to be introduced to prevent inefficient double
         # syncs in HA deployments.
-        res = (self.session.query(ConsistencyHash).
-               filter_by(hash_id=self.hash_id).first())
+        with self.session.begin(subtransactions=True):
+            res = (self.session.query(ConsistencyHash).
+                   filter_by(hash_id=self.hash_id).first())
         if not res:
             return ''
         self.hash_db_obj = res
@@ -69,19 +60,11 @@ class HashHandler(object):
 
     def put_hash(self, hash):
         hash = hash or ''
-        if not self.transaction:
-            self.transaction = self.session.begin(subtransactions=True)
-        if self.hash_db_obj is not None:
-            self.hash_db_obj.hash = hash
-        else:
-            conhash = ConsistencyHash(hash_id=self.hash_id, hash=hash)
-            self.session.merge(conhash)
-        self.close_update_session()
+        with self.session.begin(subtransactions=True):
+            if self.hash_db_obj is not None:
+                self.hash_db_obj.hash = hash
+            else:
+                conhash = ConsistencyHash(hash_id=self.hash_id, hash=hash)
+                self.session.merge(conhash)
         LOG.debug(_("Consistency hash for group %(hash_id)s updated "
                     "to %(hash)s"), {'hash_id': self.hash_id, 'hash': hash})
-
-    def close_update_session(self):
-        if not self.transaction:
-            return
-        self.transaction.commit()
-        self.transaction = None
index 55eb05d3127decff2624ba42fb8e0625ea084509..941c8f2caafde6b0f352bbdf0f791a0bfcd53769 100644 (file)
@@ -197,8 +197,6 @@ class ServerProxy(object):
                 except ValueError:
                     # response was not JSON, ignore the exception
                     pass
-            else:
-                hash_handler.close_update_session()
             ret = (response.status, response.reason, respstr, respdata)
         except httplib.HTTPException:
             # If we were using a cached connection, try again with a new one.