Merge ~blake-rouse/maas:fix-1703845-2.2 into maas:2.2

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: e1fbd9f3312516ce03a1d2fb72b1c18c3b4196b6
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~blake-rouse/maas:fix-1703845-2.2
Merge into: maas:2.2
Diff against target: 110 lines (+32/-16)
2 files modified
src/provisioningserver/rpc/clusterservice.py (+4/-1)
src/provisioningserver/rpc/tests/test_clusterservice.py (+28/-15)
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+327304@code.launchpad.net

Commit message

Backport of ba8b49322be584562654d3bfed26f03851f6ff62: Set the re-check intercal for rack to region RPC connections to the lowest value when a RPC connection is closed or lost. (Fixes lp: #1703845).

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Self-approving backport.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/provisioningserver/rpc/clusterservice.py b/src/provisioningserver/rpc/clusterservice.py
2index ea0b38c..26e2172 100644
3--- a/src/provisioningserver/rpc/clusterservice.py
4+++ b/src/provisioningserver/rpc/clusterservice.py
5@@ -1230,8 +1230,8 @@ class ClusterClientService(TimerService, object):
6 if eventloop in self.connections:
7 if self.connections[eventloop] is connection:
8 del self.connections[eventloop]
9+ # Disable DHCP when no connections to a region controller.
10 if len(self.connections) == 0:
11- # No connections to any region. DHCP should be turned off.
12 stopping_services = []
13 dhcp_v4 = service_monitor.getServiceByName("dhcpd")
14 if dhcp_v4.is_on():
15@@ -1246,3 +1246,6 @@ class ClusterClientService(TimerService, object):
16 "Lost all connections to region controllers. "
17 "Stopping service(s) %s." % ",".join(stopping_services))
18 service_monitor.ensureServices()
19+ # Lower the interval so a re-check happens sooner instead of its
20+ # currently set interval.
21+ self._update_interval(0, 0)
22diff --git a/src/provisioningserver/rpc/tests/test_clusterservice.py b/src/provisioningserver/rpc/tests/test_clusterservice.py
23index 35d84f6..e12a107 100644
24--- a/src/provisioningserver/rpc/tests/test_clusterservice.py
25+++ b/src/provisioningserver/rpc/tests/test_clusterservice.py
26@@ -471,6 +471,16 @@ class TestPatchedURI(MAASTestCase):
27 self.expectThat(uri.port, Equals(port))
28
29
30+def make_inert_client_service():
31+ service = ClusterClientService(Clock())
32+ # ClusterClientService's superclass, TimerService, creates a
33+ # LoopingCall with now=True. We neuter it here to allow
34+ # observation of the behaviour of _update_interval() for
35+ # example.
36+ service.call = (lambda: None, (), {})
37+ return service
38+
39+
40 class TestClusterClientService(MAASTestCase):
41
42 run_tests_with = MAASTwistedRunTest.make_factory(timeout=5)
43@@ -757,22 +767,34 @@ class TestClusterClientService(MAASTestCase):
44
45 def test__drop_connection(self):
46 connection = Mock()
47- service = ClusterClientService(Clock())
48+ service = make_inert_client_service()
49+ service.startService()
50 service._drop_connection(connection)
51 self.assertThat(
52 connection.transport.loseConnection,
53 MockCalledOnceWith())
54
55 def test__remove_connection_removes_from_connections(self):
56- service = ClusterClientService(Clock())
57+ service = make_inert_client_service()
58+ service.startService()
59 endpoint = Mock()
60 connection = Mock()
61 service.connections[endpoint] = connection
62 service.remove_connection(endpoint, connection)
63 self.assertThat(service.connections, Equals({}))
64
65+ def test__remove_connection_lowers_recheck_interval(self):
66+ service = make_inert_client_service()
67+ service.startService()
68+ endpoint = Mock()
69+ connection = Mock()
70+ service.connections[endpoint] = connection
71+ service.remove_connection(endpoint, connection)
72+ self.assertEquals(service.step, service.INTERVAL_LOW)
73+
74 def test__remove_connection_stops_both_dhcpd_and_dhcpd6(self):
75- service = ClusterClientService(Clock())
76+ service = make_inert_client_service()
77+ service.startService()
78 endpoint = Mock()
79 connection = Mock()
80 service.connections[endpoint] = connection
81@@ -941,17 +963,8 @@ class TestClusterClientServiceIntervals(MAASTestCase):
82
83 run_tests_with = MAASTwistedRunTest.make_factory(timeout=5)
84
85- def make_inert_client_service(self):
86- service = ClusterClientService(Clock())
87- # ClusterClientService's superclass, TimerService, creates a
88- # LoopingCall with now=True. We neuter it here to allow
89- # observation of the behaviour of _update_interval() for
90- # example.
91- service.call = (lambda: None, (), {})
92- return service
93-
94 def test__calculate_interval(self):
95- service = self.make_inert_client_service()
96+ service = make_inert_client_service()
97 service.startService()
98 service.clock.advance(self.time_running)
99 self.assertEqual(
100@@ -985,8 +998,8 @@ class TestClusterClient(MAASTestCase):
101 def make_running_client(self):
102 client = clusterservice.ClusterClient(
103 address=("example.com", 1234), eventloop="eventloop:pid=12345",
104- service=ClusterClientService(Clock()))
105- client.service.running = True
106+ service=make_inert_client_service())
107+ client.service.startService()
108 return client
109
110 def patch_authenticate_for_success(self, client):

Subscribers

People subscribed via source and target branches