Merge lp:~allenap/maas/keep-interval-low-at-start into lp:~maas-committers/maas/trunk

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 3165
Proposed branch: lp:~allenap/maas/keep-interval-low-at-start
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 103 lines (+30/-0)
2 files modified
src/provisioningserver/rpc/clusterservice.py (+18/-0)
src/provisioningserver/rpc/tests/test_clusterservice.py (+12/-0)
To merge this branch: bzr merge lp:~allenap/maas/keep-interval-low-at-start
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+236800@code.launchpad.net

Commit message

Check frequently for new event-loops for a period after starting.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/rpc/clusterservice.py'
2--- src/provisioningserver/rpc/clusterservice.py 2014-10-01 10:19:28 +0000
3+++ src/provisioningserver/rpc/clusterservice.py 2014-10-02 00:34:23 +0000
4@@ -486,12 +486,16 @@
5
6 :ivar connections: A mapping of eventloop names to protocol
7 instances connected to it.
8+ :ivar time_started: Records the time that `startService` was last called,
9+ or `None` if it hasn't yet.
10 """
11
12 INTERVAL_LOW = 2 # seconds.
13 INTERVAL_MID = 10 # seconds.
14 INTERVAL_HIGH = 30 # seconds.
15
16+ time_started = None
17+
18 def __init__(self, reactor):
19 super(ClusterClientService, self).__init__(
20 self._calculate_interval(None, None), self.update)
21@@ -506,6 +510,10 @@
22 # occur in the URL's netloc portion as part of a port specification.
23 twisted.web.client._URI = PatchedURI
24
25+ def startService(self):
26+ self.time_started = self.clock.seconds()
27+ super(ClusterClientService, self).startService()
28+
29 def getClient(self):
30 """Returns a :class:`common.Client` connected to a region.
31
32@@ -572,11 +580,21 @@
33 connections, so that this can quickly obtain its first
34 connection.
35
36+ The interval is also `INTERVAL_LOW` for a time after the service
37+ starts. This helps to get everything connected quickly when the
38+ cluster is started at a similar time to the region.
39+
40 The interval changes to `INTERVAL_MID` seconds when there are
41 some connections, but fewer than there are event-loops.
42
43 After that it drops back to `INTERVAL_HIGH` seconds.
44 """
45+ if self.time_started is not None:
46+ time_running = self.clock.seconds() - self.time_started
47+ if time_running < self.INTERVAL_HIGH:
48+ # This service has recently started; keep trying regularly.
49+ return self.INTERVAL_LOW
50+
51 if num_eventloops is None:
52 # The region is not available; keep trying regularly.
53 return self.INTERVAL_LOW
54
55=== modified file 'src/provisioningserver/rpc/tests/test_clusterservice.py'
56--- src/provisioningserver/rpc/tests/test_clusterservice.py 2014-10-01 09:45:49 +0000
57+++ src/provisioningserver/rpc/tests/test_clusterservice.py 2014-10-02 00:34:23 +0000
58@@ -673,26 +673,37 @@
59
60 scenarios = (
61 ("initial", {
62+ "time_running": 0,
63 "num_eventloops": None,
64 "num_connections": None,
65 "expected": ClusterClientService.INTERVAL_LOW,
66 }),
67+ ("shortly-after-start", {
68+ "time_running": 10,
69+ "num_eventloops": 1, # same as num_connections.
70+ "num_connections": 1, # same as num_eventloops.
71+ "expected": ClusterClientService.INTERVAL_LOW,
72+ }),
73 ("no-event-loops", {
74+ "time_running": 1000,
75 "num_eventloops": 0,
76 "num_connections": sentinel.undefined,
77 "expected": ClusterClientService.INTERVAL_LOW,
78 }),
79 ("no-connections", {
80+ "time_running": 1000,
81 "num_eventloops": 1, # anything > 1.
82 "num_connections": 0,
83 "expected": ClusterClientService.INTERVAL_LOW,
84 }),
85 ("fewer-connections-than-event-loops", {
86+ "time_running": 1000,
87 "num_eventloops": 2, # anything > num_connections.
88 "num_connections": 1, # anything > 0.
89 "expected": ClusterClientService.INTERVAL_MID,
90 }),
91 ("default", {
92+ "time_running": 1000,
93 "num_eventloops": 3, # same as num_connections.
94 "num_connections": 3, # same as num_eventloops.
95 "expected": ClusterClientService.INTERVAL_HIGH,
96@@ -711,6 +722,7 @@
97 def test__calculate_interval(self):
98 service = self.make_inert_client_service()
99 service.startService()
100+ service.clock.advance(self.time_running)
101 self.assertEqual(
102 self.expected, service._calculate_interval(
103 self.num_eventloops, self.num_connections))