Add IPAllocation object to session info to stop GC
This adds the IPAllocation object created in the _store_ip_allocation
method to the session info dictionary to prevent it from being
immediately garbage collected. This is necessary because otherwise a
new persistent object will be created when the fixed_ips relationship
is referenced during the rest of the port create/update opertions.
This persistent object will then interfere with a retry operation
that uses the same session if it tries to create a conflicting record.
By preventing the object from being garbage collected, the reference
to fixed IPs will re-use the newly created sqlalchemy object instead
which will properly be cleaned up on a rollback.
This also removes the 'passive_delete' option from the fixed_ips
relationship on ports because IPAllocation objects would now be
left in the session after port deletes. At first glance, this might
look like a performance penalty because fixed_ips would be looked
up before port deletes; however, we already do that in the IPAM
code as well as the ML2 code so this relationship is already being
loaded on the delete_port operation.
Closes-Bug: #1556178
Change-Id: Ieee1343bb90cf111c55e00b9cabc27943b46c350
(cherry picked from commit 7d9169967f
)
This commit is contained in:
parent
e9622b0bb0
commit
b30eb16bd0
|
@ -107,6 +107,12 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin):
|
|||
subnet_id=subnet_id
|
||||
)
|
||||
context.session.add(allocated)
|
||||
# NOTE(kevinbenton): We add this to the session info so the sqlalchemy
|
||||
# object isn't immediately garbage collected. Otherwise when the
|
||||
# fixed_ips relationship is referenced a new persistent object will be
|
||||
# added to the session that will interfere with retry operations.
|
||||
# See bug 1556178 for details.
|
||||
context.session.info.setdefault('allocated_ips', []).append(allocated)
|
||||
|
||||
def _make_subnet_dict(self, subnet, fields=None, context=None):
|
||||
res = {'id': subnet['id'],
|
||||
|
|
|
@ -119,7 +119,8 @@ class Port(model_base.BASEV2, HasId, HasTenant):
|
|||
network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id"),
|
||||
nullable=False)
|
||||
fixed_ips = orm.relationship(IPAllocation, backref='port', lazy='joined',
|
||||
passive_deletes='all')
|
||||
cascade='all, delete-orphan')
|
||||
|
||||
mac_address = sa.Column(sa.String(32), nullable=False)
|
||||
admin_state_up = sa.Column(sa.Boolean(), nullable=False)
|
||||
status = sa.Column(sa.String(16), nullable=False)
|
||||
|
|
Loading…
Reference in New Issue