Merge "BSN: Remove db lock and add missing contexts"

This commit is contained in:
Jenkins 2014-07-01 19:21:56 +00:00 committed by Gerrit Code Review
commit 8d9a7def8b
3 changed files with 21 additions and 13 deletions

View File

@ -55,13 +55,13 @@ class HashHandler(object):
if self.transaction:
raise MultipleReadForUpdateCalls()
self.transaction = self.session.begin(subtransactions=True)
# Lock for update here to prevent another server from reading the hash
# while this one is in the middle of a transaction.
# This may not lock the SQL table in MySQL Galera deployments
# but that's okay because the worst case is a double-sync
# 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).
with_lockmode('update').first())
filter_by(hash_id=self.hash_id).first())
if not res:
return ''
self.hash_db_obj = res

View File

@ -968,6 +968,7 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
self.servers.rest_delete_router(tenant_id, router_id)
return ret_val
@put_context_in_serverpool
def add_router_interface(self, context, router_id, interface_info):
LOG.debug(_("NeutronRestProxyV2: add_router_interface() called"))
@ -996,6 +997,7 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
intf_details)
return new_intf_info
@put_context_in_serverpool
def remove_router_interface(self, context, router_id, interface_info):
LOG.debug(_("NeutronRestProxyV2: remove_router_interface() called"))
@ -1087,6 +1089,7 @@ class NeutronRestProxyV2(NeutronRestProxyV2Base,
else:
self._send_floatingip_update(context)
@put_context_in_serverpool
def disassociate_floatingips(self, context, port_id):
LOG.debug(_("NeutronRestProxyV2: diassociate_floatingips() called"))
super(NeutronRestProxyV2, self).disassociate_floatingips(context,

View File

@ -35,6 +35,7 @@ import httplib
import os
import socket
import ssl
import weakref
import eventlet
import eventlet.corolocal
@ -266,14 +267,18 @@ class ServerPool(object):
def set_context(self, context):
# this context needs to be local to the greenthread
# so concurrent requests don't use the wrong context
self.contexts[eventlet.corolocal.get_ident()] = context
# so concurrent requests don't use the wrong context.
# Use a weakref so the context is garbage collected
# after the plugin is done with it.
ref = weakref.ref(context)
self.contexts[eventlet.corolocal.get_ident()] = ref
def pop_context(self):
# Don't store these contexts after use. They should only
# last for one request.
def get_context_ref(self):
# Try to get the context cached for this thread. If one
# doesn't exist or if it's been garbage collected, this will
# just return None.
try:
return self.contexts.pop(eventlet.corolocal.get_ident())
return self.contexts[eventlet.corolocal.get_ident()]()
except KeyError:
return None
@ -403,7 +408,7 @@ class ServerPool(object):
@utils.synchronized('bsn-rest-call')
def rest_call(self, action, resource, data, headers, ignore_codes,
timeout=False):
hash_handler = cdb.HashHandler(context=self.pop_context())
hash_handler = cdb.HashHandler(context=self.get_context_ref())
good_first = sorted(self.servers, key=lambda x: x.failed)
first_response = None
for active_server in good_first: