Fix relationship event handler for flushes and nested
Handle interim flushes by tracking 'new' objects in session.info until commit time. This is necessary because new objects will no longer be in 'session.new' during the before_commit event if flushes have occurred. Don't load relationships until final commit in nested commits. This ensures we are on the outermost commit that will end the session before loading up all of the relationships. Partially-Implements: blueprint enginefacade-switch Change-Id: Id0f79ebaafc446bb28363d281249f02eacd1e28d
This commit is contained in:
parent
e022c1a182
commit
b02bbf8ba5
@ -15,6 +15,7 @@
|
||||
|
||||
import contextlib
|
||||
import copy
|
||||
import weakref
|
||||
|
||||
from debtcollector import removals
|
||||
from neutron_lib.db import api
|
||||
@ -264,12 +265,25 @@ def sqla_remove_all():
|
||||
del _REGISTERED_SQLA_EVENTS[:]
|
||||
|
||||
|
||||
@event.listens_for(orm.session.Session, "after_flush")
|
||||
def add_to_rel_load_list(session, flush_context=None):
|
||||
# keep track of new items to load relationships on during commit
|
||||
session.info.setdefault('_load_rels', weakref.WeakSet()).update(
|
||||
session.new)
|
||||
|
||||
|
||||
@event.listens_for(orm.session.Session, "before_commit")
|
||||
def load_one_to_manys(session):
|
||||
# TODO(kevinbenton): we should be able to remove this after we
|
||||
# have eliminated all places where related objects are constructed
|
||||
# using a key rather than a relationship.
|
||||
for new_object in session.new:
|
||||
|
||||
add_to_rel_load_list(session) # capture any new objects
|
||||
if session.transaction.nested:
|
||||
# wait until final commit
|
||||
return
|
||||
|
||||
for new_object in session.info.pop('_load_rels', []):
|
||||
state = sqlalchemy.inspect(new_object)
|
||||
|
||||
# set up relationship loading so that we can call lazy
|
||||
|
@ -55,6 +55,7 @@ from neutron.db import ipam_backend_mixin
|
||||
from neutron.db.models import l3 as l3_models
|
||||
from neutron.db.models import securitygroup as sg_models
|
||||
from neutron.db import models_v2
|
||||
from neutron.db import rbac_db_models
|
||||
from neutron.db import standard_attr
|
||||
from neutron.ipam import exceptions as ipam_exc
|
||||
from neutron.tests import base
|
||||
@ -6062,13 +6063,29 @@ class TestSubnetPoolsV2(NeutronDbPluginV2TestCase):
|
||||
class DbModelMixin(object):
|
||||
"""DB model tests."""
|
||||
def test_make_network_dict_outside_engine_facade_manager(self):
|
||||
mock.patch.object(directory, 'get_plugin').start()
|
||||
ctx = context.get_admin_context()
|
||||
with db_api.context_manager.writer.using(ctx):
|
||||
network = models_v2.Network(name="net_net", status="OK",
|
||||
admin_state_up=True)
|
||||
ctx.session.add(network)
|
||||
with db_api.autonested_transaction(ctx.session):
|
||||
sg = sg_models.SecurityGroup(name='sg', description='sg')
|
||||
ctx.session.add(sg)
|
||||
# ensure db rels aren't loaded until commit for network object
|
||||
# by sharing after a nested transaction
|
||||
ctx.session.add(
|
||||
rbac_db_models.NetworkRBAC(object_id=network.id,
|
||||
action='access_as_shared',
|
||||
tenant_id=network.tenant_id,
|
||||
target_tenant='*')
|
||||
)
|
||||
net2 = models_v2.Network(name="net_net2", status="OK",
|
||||
admin_state_up=True)
|
||||
ctx.session.add(net2)
|
||||
pl = db_base_plugin_common.DbBasePluginCommon()
|
||||
self.assertFalse(pl._make_network_dict(network, context=ctx)['shared'])
|
||||
self.assertTrue(pl._make_network_dict(network, context=ctx)['shared'])
|
||||
self.assertFalse(pl._make_network_dict(net2, context=ctx)['shared'])
|
||||
|
||||
def test_repr(self):
|
||||
"""testing the string representation of 'model' classes."""
|
||||
|
@ -237,6 +237,7 @@ class TestL3GwModeMixin(testlib_api.SqlTestCase):
|
||||
self.context.session.add(self.fip_int_ip_info)
|
||||
self.context.session.add(self.fip)
|
||||
self.context.session.flush()
|
||||
self.context.session.expire_all()
|
||||
self.fip_request = {'port_id': FAKE_FIP_INT_PORT_ID,
|
||||
'tenant_id': self.tenant_id}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user