Browse Source

Merge "Limit max ports per rpc for dhcp_ready_on_ports()" into stable/queens

changes/71/673171/1
Zuul 1 month ago
parent
commit
73608a8169
2 changed files with 33 additions and 2 deletions
  1. 7
    2
      neutron/agent/dhcp/agent.py
  2. 26
    0
      neutron/tests/unit/agent/dhcp/test_agent.py

+ 7
- 2
neutron/agent/dhcp/agent.py View File

@@ -47,6 +47,8 @@ _SYNC_STATE_LOCK = lockutils.ReaderWriterLock()
47 47
 
48 48
 DEFAULT_PRIORITY = 255
49 49
 
50
+DHCP_READY_PORTS_SYNC_MAX = 64
51
+
50 52
 
51 53
 def _sync_lock(f):
52 54
     """Decorator to block all operations for a global sync call."""
@@ -222,8 +224,11 @@ class DhcpAgent(manager.Manager):
222 224
             # this is just watching a set so we can do it really frequently
223 225
             eventlet.sleep(0.1)
224 226
             if self.dhcp_ready_ports:
225
-                ports_to_send = self.dhcp_ready_ports
226
-                self.dhcp_ready_ports = set()
227
+                ports_to_send = set()
228
+                for port_count in range(min(len(self.dhcp_ready_ports),
229
+                                            DHCP_READY_PORTS_SYNC_MAX)):
230
+                    ports_to_send.add(self.dhcp_ready_ports.pop())
231
+
227 232
                 try:
228 233
                     self.plugin_rpc.dhcp_ready_on_ports(ports_to_send)
229 234
                     continue

+ 26
- 0
neutron/tests/unit/agent/dhcp/test_agent.py View File

@@ -458,6 +458,32 @@ class TestDhcpAgent(base.BaseTestCase):
458 458
         # should have been called with all ports again after the failure
459 459
         ready.assert_has_calls([mock.call(set(range(4)))] * 2)
460 460
 
461
+    def test_dhcp_ready_ports_loop_with_limit_ports_per_call(self):
462
+        dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
463
+        sync_max = dhcp_agent.DHCP_READY_PORTS_SYNC_MAX
464
+        port_count = sync_max + 1
465
+        dhcp.dhcp_ready_ports = set(range(port_count))
466
+
467
+        with mock.patch.object(dhcp.plugin_rpc,
468
+                               'dhcp_ready_on_ports') as ready:
469
+            # exit after 2 iterations
470
+            with mock.patch.object(dhcp_agent.eventlet, 'sleep',
471
+                                   side_effect=[0, 0, RuntimeError]):
472
+                with testtools.ExpectedException(RuntimeError):
473
+                    dhcp._dhcp_ready_ports_loop()
474
+
475
+        # all ports should have been processed
476
+        self.assertEqual(set(), dhcp.dhcp_ready_ports)
477
+        # two calls are expected, one with DHCP_READY_PORTS_SYNC_MAX ports,
478
+        # second one with one port
479
+        self.assertEqual(2, ready.call_count)
480
+        self.assertEqual(sync_max, len(ready.call_args_list[0][0][0]))
481
+        self.assertEqual(1, len(ready.call_args_list[1][0][0]))
482
+        # all ports need to be ready
483
+        ports_ready = (ready.call_args_list[0][0][0] |
484
+                       ready.call_args_list[1][0][0])
485
+        self.assertEqual(set(range(port_count)), ports_ready)
486
+
461 487
     def test_dhcp_ready_ports_updates_after_enable_dhcp(self):
462 488
         dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
463 489
         self.assertEqual(set(), dhcp.dhcp_ready_ports)

Loading…
Cancel
Save