]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Avoid DetachedInstanceError after session rollback
authorEugene Nikanorov <enikanorov@mirantis.com>
Mon, 23 Feb 2015 10:29:08 +0000 (13:29 +0300)
committerEugene Nikanorov <enikanorov@mirantis.com>
Thu, 26 Feb 2015 10:12:28 +0000 (13:12 +0300)
In some cases this exception is thrown while accessing Agent
object from logging statement after a transaction was rolled back.
There is a unit test that covers thsi code patch, but the issue
is not reproducible with sqlite.
Just avoid accessing db object after session had been closed.

Change-Id: Iff6b72156b08f177bd0c71f6ba93d3bf46c82fa4
Closes-Bug: #1424578

neutron/scheduler/dhcp_agent_scheduler.py

index 67f0aca7136a8d0720a22b99d9d9ec2475fced2c..09afabfa590f4bbc243fe0f211176f91cc38f4d8 100644 (file)
@@ -38,10 +38,13 @@ class ChanceScheduler(object):
     def _schedule_bind_network(self, context, agents, network_id):
         for agent in agents:
             context.session.begin(subtransactions=True)
+            # saving agent_id to use it after rollback to avoid
+            # DetachedInstanceError
+            agent_id = agent.id
+            binding = agentschedulers_db.NetworkDhcpAgentBinding()
+            binding.dhcp_agent_id = agent_id
+            binding.network_id = network_id
             try:
-                binding = agentschedulers_db.NetworkDhcpAgentBinding()
-                binding.dhcp_agent = agent
-                binding.network_id = network_id
                 context.session.add(binding)
                 # try to actually write the changes and catch integrity
                 # DBDuplicateEntry
@@ -49,11 +52,11 @@ class ChanceScheduler(object):
             except db_exc.DBDuplicateEntry:
                 # it's totally ok, someone just did our job!
                 context.session.rollback()
-                LOG.info(_LI('Agent %s already present'), agent)
+                LOG.info(_LI('Agent %s already present'), agent_id)
             LOG.debug('Network %(network_id)s is scheduled to be '
                       'hosted by DHCP agent %(agent_id)s',
                       {'network_id': network_id,
-                       'agent_id': agent})
+                       'agent_id': agent_id})
 
     def schedule(self, plugin, context, network):
         """Schedule the network to active DHCP agent(s).