Skip to content

Commit b00d88f

Browse files
fix(core): prefer use of time.monotonic
`time.time()` is subject to change sin system local time and can trigger unexpected behaviour. Prefer the use of `time.monotonic` instead of `time.time` since we are not making use of the actual time, only an amount of time elapsed. Fixes #722
1 parent 144b696 commit b00d88f

File tree

5 files changed

+15
-15
lines changed

5 files changed

+15
-15
lines changed

kazoo/handlers/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ def create_tcp_connection(
212212
# this ugliness...
213213
timeout = module.getdefaulttimeout()
214214
if timeout is not None:
215-
end = time.time() + timeout
215+
end = time.monotonic() + timeout
216216
sock = None
217217

218218
while True:
219-
timeout_at = end if end is None else end - time.time()
219+
timeout_at = end if end is None else end - time.monotonic()
220220
# The condition is not '< 0' here because socket.settimeout treats 0 as
221221
# a special case to put the socket in non-blocking mode.
222222
if timeout_at is not None and timeout_at <= 0:

kazoo/protocol/connection.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,19 @@ def __init__(self, hosts, connection_func, socket_handling):
109109

110110
def __iter__(self):
111111
if not self.last_attempt:
112-
self.last_attempt = time.time()
112+
self.last_attempt = time.monotonic()
113113
delay = 0.5
114114
while True:
115115
yield self._next_server(delay)
116116

117117
def _next_server(self, delay):
118118
jitter = random.randint(0, 100) / 100.0
119-
while time.time() < self.last_attempt + delay + jitter:
119+
while time.monotonic() < self.last_attempt + delay + jitter:
120120
# Skip rw ping checks if its too soon
121121
return False
122122
for host, port in self.hosts:
123123
log.debug("Pinging server for r/w: %s:%s", host, port)
124-
self.last_attempt = time.time()
124+
self.last_attempt = time.monotonic()
125125
try:
126126
with self.socket_handling():
127127
sock = self.connection((host, port))
@@ -136,7 +136,7 @@ def _next_server(self, delay):
136136
return False
137137

138138
# Add some jitter between host pings
139-
while time.time() < self.last_attempt + jitter:
139+
while time.monotonic() < self.last_attempt + jitter:
140140
return False
141141
delay *= 2
142142

@@ -617,14 +617,14 @@ def _connect_attempt(self, host, hostip, port, retry):
617617
connect_timeout = connect_timeout / 1000.0
618618
retry.reset()
619619
self.ping_outstanding.clear()
620-
last_send = time.time()
620+
last_send = time.monotonic()
621621
with self._socket_error_handling():
622622
while not self.client._stopped.is_set():
623623
# Watch for something to read or send
624624
jitter_time = random.randint(1, 40) / 100.0
625625
deadline = last_send + read_timeout / 2.0 - jitter_time
626626
# Ensure our timeout is positive
627-
timeout = max([deadline - time.time(), jitter_time])
627+
timeout = max([deadline - time.monotonic(), jitter_time])
628628
s = self.handler.select(
629629
[self._socket, self._read_sock], [], [], timeout
630630
)[0]
@@ -646,12 +646,12 @@ def _connect_attempt(self, host, hostip, port, retry):
646646
if self._read_sock in s:
647647
self._send_request(read_timeout, connect_timeout)
648648
# Requests act as implicit pings.
649-
last_send = time.time()
649+
last_send = time.monotonic()
650650
continue
651651

652-
if time.time() >= deadline:
652+
if time.monotonic() >= deadline:
653653
self._send_ping(connect_timeout)
654-
last_send = time.time()
654+
last_send = time.monotonic()
655655
self.logger.info("Closing connection to %s:%s", host, port)
656656
client._session_callback(KeeperState.CLOSED)
657657
return STOP_CONNECTING

kazoo/recipe/watchers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,4 +449,4 @@ def _inner_start(self):
449449

450450
def _children_watcher(self, async_result, event):
451451
self.children_changed.set()
452-
async_result.set(time.time())
452+
async_result.set(time.monotonic())

kazoo/retry.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def __call__(self, func, *args, **kwargs):
128128
while True:
129129
try:
130130
if self.deadline is not None and self._cur_stoptime is None:
131-
self._cur_stoptime = time.time() + self.deadline
131+
self._cur_stoptime = time.monotonic() + self.deadline
132132
return func(*args, **kwargs)
133133
except ConnectionClosedError:
134134
raise
@@ -144,7 +144,7 @@ def __call__(self, func, *args, **kwargs):
144144

145145
if (
146146
self._cur_stoptime is not None
147-
and time.time() + sleeptime >= self._cur_stoptime
147+
and time.monotonic() + sleeptime >= self._cur_stoptime
148148
):
149149
raise RetryFailedError("Exceeded retry deadline")
150150

kazoo/tests/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def __init__(
9595
timeout=None,
9696
wait=None,
9797
exception=None,
98-
getnow=(lambda: time.time),
98+
getnow=(lambda: time.monotonic),
9999
getsleep=(lambda: time.sleep),
100100
):
101101
if timeout is not None:

0 commit comments

Comments
 (0)