diff --git a/redis/client.py b/redis/client.py index 2bacbe14ac..36e0b35df3 100755 --- a/redis/client.py +++ b/redis/client.py @@ -950,7 +950,7 @@ def check_health(self) -> None: "did you forget to call subscribe() or psubscribe()?" ) - if conn.health_check_interval and time.time() > conn.next_health_check: + if conn.health_check_interval and time.monotonic() > conn.next_health_check: conn.send_command("PING", self.HEALTH_CHECK_MESSAGE, check_health=False) self.health_check_response_counter += 1 @@ -1100,12 +1100,12 @@ def get_message( """ if not self.subscribed: # Wait for subscription - start_time = time.time() + start_time = time.monotonic() if self.subscribed_event.wait(timeout) is True: # The connection was subscribed during the timeout time frame. # The timeout should be adjusted based on the time spent # waiting for the subscription - time_spent = time.time() - start_time + time_spent = time.monotonic() - start_time timeout = max(0.0, timeout - time_spent) else: # The connection isn't subscribed to any channels or patterns, diff --git a/redis/commands/search/commands.py b/redis/commands/search/commands.py index 1db57c23a5..96c6d9c2af 100644 --- a/redis/commands/search/commands.py +++ b/redis/commands/search/commands.py @@ -500,7 +500,7 @@ def search( For more information see `FT.SEARCH `_. """ # noqa args, query = self._mk_query_args(query, query_params=query_params) - st = time.time() + st = time.monotonic() options = {} if get_protocol_version(self.client) not in ["3", 3]: @@ -512,7 +512,7 @@ def search( return res return self._parse_results( - SEARCH_CMD, res, query=query, duration=(time.time() - st) * 1000.0 + SEARCH_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0 ) def explain( @@ -602,7 +602,7 @@ def profile( Each parameter has a name and a value. """ - st = time.time() + st = time.monotonic() cmd = [PROFILE_CMD, self.index_name, ""] if limited: cmd.append("LIMITED") @@ -621,7 +621,7 @@ def profile( res = self.execute_command(*cmd) return self._parse_results( - PROFILE_CMD, res, query=query, duration=(time.time() - st) * 1000.0 + PROFILE_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0 ) def spellcheck(self, query, distance=None, include=None, exclude=None): @@ -940,7 +940,7 @@ async def search( For more information see `FT.SEARCH `_. """ # noqa args, query = self._mk_query_args(query, query_params=query_params) - st = time.time() + st = time.monotonic() options = {} if get_protocol_version(self.client) not in ["3", 3]: @@ -952,7 +952,7 @@ async def search( return res return self._parse_results( - SEARCH_CMD, res, query=query, duration=(time.time() - st) * 1000.0 + SEARCH_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0 ) async def aggregate( diff --git a/redis/connection.py b/redis/connection.py index 43501800c8..a298542c03 100644 --- a/redis/connection.py +++ b/redis/connection.py @@ -4,11 +4,11 @@ import ssl import sys import threading +import time import weakref from abc import abstractmethod from itertools import chain from queue import Empty, Full, LifoQueue -from time import time from typing import Any, Callable, Dict, List, Optional, Type, TypeVar, Union from urllib.parse import parse_qs, unquote, urlparse @@ -542,7 +542,7 @@ def _ping_failed(self, error): def check_health(self): """Check the health of the connection with a PING/PONG""" - if self.health_check_interval and time() > self.next_health_check: + if self.health_check_interval and time.monotonic() > self.next_health_check: self.retry.call_with_retry(self._send_ping, self._ping_failed) def send_packed_command(self, command, check_health=True): @@ -632,7 +632,7 @@ def read_response( raise if self.health_check_interval: - self.next_health_check = time() + self.health_check_interval + self.next_health_check = time.monotonic() + self.health_check_interval if isinstance(response, ResponseError): try: diff --git a/tests/conftest.py b/tests/conftest.py index c485d626ca..7eaccb1acb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -237,7 +237,7 @@ def wait_for_cluster_creation(redis_url, cluster_nodes, timeout=60): :param cluster_nodes: The number of nodes in the cluster :param timeout: the amount of time to wait (in seconds) """ - now = time.time() + now = time.monotonic() end_time = now + timeout client = None print(f"Waiting for {cluster_nodes} cluster nodes to become available") @@ -250,7 +250,7 @@ def wait_for_cluster_creation(redis_url, cluster_nodes, timeout=60): except RedisClusterException: pass time.sleep(1) - now = time.time() + now = time.monotonic() if now >= end_time: available_nodes = 0 if client is None else len(client.get_nodes()) raise RedisClusterException( diff --git a/tests/test_connection_pool.py b/tests/test_connection_pool.py index 65f42923fe..c92d84c226 100644 --- a/tests/test_connection_pool.py +++ b/tests/test_connection_pool.py @@ -167,11 +167,11 @@ def test_connection_pool_blocks_until_timeout(self, master_host): ) pool.get_connection() - start = time.time() + start = time.monotonic() with pytest.raises(redis.ConnectionError): pool.get_connection() # we should have waited at least 0.1 seconds - assert time.time() - start >= 0.1 + assert time.monotonic() - start >= 0.1 def test_connection_pool_blocks_until_conn_available(self, master_host): """ @@ -188,10 +188,10 @@ def target(): time.sleep(0.1) pool.release(c1) - start = time.time() + start = time.monotonic() Thread(target=target).start() pool.get_connection() - assert time.time() - start >= 0.1 + assert time.monotonic() - start >= 0.1 def test_reuse_previously_released_connection(self, master_host): connection_kwargs = {"host": master_host[0], "port": master_host[1]} @@ -679,18 +679,18 @@ def r(self, request): return _get_client(redis.Redis, request, health_check_interval=self.interval) def assert_interval_advanced(self, connection): - diff = connection.next_health_check - time.time() + diff = connection.next_health_check - time.monotonic() assert self.interval > diff > (self.interval - 1) def test_health_check_runs(self, r): - r.connection.next_health_check = time.time() - 1 + r.connection.next_health_check = time.monotonic() - 1 r.connection.check_health() self.assert_interval_advanced(r.connection) def test_arbitrary_command_invokes_health_check(self, r): # invoke a command to make sure the connection is entirely setup r.get("foo") - r.connection.next_health_check = time.time() + r.connection.next_health_check = time.monotonic() with mock.patch.object( r.connection, "send_command", wraps=r.connection.send_command ) as m: diff --git a/tests/test_pubsub.py b/tests/test_pubsub.py index fb46772af3..9ead455af3 100644 --- a/tests/test_pubsub.py +++ b/tests/test_pubsub.py @@ -23,7 +23,7 @@ def wait_for_message( pubsub, timeout=0.5, ignore_subscribe_messages=False, node=None, func=None ): - now = time.time() + now = time.monotonic() timeout = now + timeout while now < timeout: if node: @@ -39,7 +39,7 @@ def wait_for_message( if message is not None: return message time.sleep(0.01) - now = time.time() + now = time.monotonic() return None