Revision a6db1af2
b/lib/mcpu.py | ||
---|---|---|
81 | 81 |
"_random_fn", |
82 | 82 |
"_start_time", |
83 | 83 |
"_time_fn", |
84 |
"_running_timeout", |
|
84 | 85 |
] |
85 | 86 |
|
86 | 87 |
_TIMEOUT_PER_ATTEMPT = _CalculateLockAttemptTimeouts() |
... | ... | |
103 | 104 |
self._time_fn = _time_fn |
104 | 105 |
self._random_fn = _random_fn |
105 | 106 |
|
106 |
self._start_time = None |
|
107 |
try: |
|
108 |
timeout = self._TIMEOUT_PER_ATTEMPT[attempt] |
|
109 |
except IndexError: |
|
110 |
# No more timeouts, do blocking acquire |
|
111 |
timeout = None |
|
112 |
|
|
113 |
self._running_timeout = locking.RunningTimeout(timeout, False, |
|
114 |
_time_fn=_time_fn) |
|
107 | 115 |
|
108 | 116 |
def NextAttempt(self): |
109 | 117 |
"""Returns the strategy for the next attempt. |
... | ... | |
117 | 125 |
"""Returns the remaining timeout. |
118 | 126 |
|
119 | 127 |
""" |
120 |
try: |
|
121 |
timeout = self._TIMEOUT_PER_ATTEMPT[self._attempt] |
|
122 |
except IndexError: |
|
123 |
# No more timeouts, do blocking acquire |
|
124 |
return None |
|
125 |
|
|
126 |
# Get start time on first calculation |
|
127 |
if self._start_time is None: |
|
128 |
self._start_time = self._time_fn() |
|
129 |
|
|
130 |
# Calculate remaining time for this attempt |
|
131 |
remaining_timeout = self._start_time + timeout - self._time_fn() |
|
132 |
|
|
133 |
# Add a small variation (-/+ 5%) to timeouts. This helps in situations |
|
134 |
# where two or more jobs are fighting for the same lock(s). |
|
135 |
variation_range = remaining_timeout * 0.1 |
|
136 |
remaining_timeout += ((self._random_fn() * variation_range) - |
|
137 |
(variation_range * 0.5)) |
|
128 |
timeout = self._running_timeout.Remaining() |
|
138 | 129 |
|
139 |
# Make sure timeout is >= 0 |
|
140 |
remaining_timeout = max(0.0, remaining_timeout) |
|
130 |
if timeout is not None: |
|
131 |
# Add a small variation (-/+ 5%) to timeout. This helps in situations |
|
132 |
# where two or more jobs are fighting for the same lock(s). |
|
133 |
variation_range = timeout * 0.1 |
|
134 |
timeout += ((self._random_fn() * variation_range) - |
|
135 |
(variation_range * 0.5)) |
|
141 | 136 |
|
142 |
return remaining_timeout
|
|
137 |
return timeout |
|
143 | 138 |
|
144 | 139 |
|
145 | 140 |
class OpExecCbBase: |
b/test/ganeti.mcpu_unittest.py | ||
---|---|---|
40 | 40 |
self.assertEqual(strat._attempt, 0) |
41 | 41 |
|
42 | 42 |
prev = None |
43 |
for _ in range(len(mcpu._LockAttemptTimeoutStrategy._TIMEOUT_PER_ATTEMPT)):
|
|
43 |
for i in range(len(mcpu._LockAttemptTimeoutStrategy._TIMEOUT_PER_ATTEMPT)):
|
|
44 | 44 |
timeout = strat.CalcRemainingTimeout() |
45 | 45 |
self.assert_(timeout is not None) |
46 | 46 |
|
47 | 47 |
self.assert_(timeout <= 10.0) |
48 |
self.assert_(timeout >= 0.0) |
|
48 | 49 |
self.assert_(prev is None or timeout >= prev) |
49 | 50 |
|
50 | 51 |
strat = strat.NextAttempt() |
52 |
self.assertEqual(strat._attempt, i + 1) |
|
51 | 53 |
|
52 | 54 |
prev = timeout |
53 | 55 |
|
54 |
self.assert_(strat.CalcRemainingTimeout() is None) |
|
56 |
for _ in range(10): |
|
57 |
self.assert_(strat.CalcRemainingTimeout() is None) |
|
55 | 58 |
|
56 | 59 |
|
57 | 60 |
if __name__ == "__main__": |
Also available in: Unified diff