Use monotonic time for query timing (#1070)

To fix intermittent issues with [windows
CI](https://github.com/python-kasa/python-kasa/actions/runs/9952477932/job/27493918272?pr=1068).
Probably better to use monotonic here anyway.

```
FAILED kasa/tests/test_smartdevice.py::test_update_module_update_delays[L530E(EU)_3.0_1.1.6.json-SMART] - ValueError: Clock moved backwards. Refusing to generate ID.
```
This commit is contained in:
Steven B. 2024-07-16 13:25:32 +01:00 committed by GitHub
parent 7e9b1687d0
commit b220beb811
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 11 additions and 9 deletions

View File

@ -72,7 +72,7 @@ class HttpClient:
# Once we know a device needs a wait between sequential queries always wait
# first rather than keep erroring then waiting.
if self._wait_between_requests:
now = time.time()
now = time.monotonic()
gap = now - self._last_request_time
if gap < self._wait_between_requests:
sleep = self._wait_between_requests - gap
@ -123,7 +123,7 @@ class HttpClient:
ex,
)
self._wait_between_requests = self.WAIT_BETWEEN_REQUESTS_ON_OSERROR
self._last_request_time = time.time()
self._last_request_time = time.monotonic()
raise _ConnectionError(
f"Device connection error: {self._config.host}: {ex}", ex
) from ex
@ -140,7 +140,7 @@ class HttpClient:
# For performance only request system time if waiting is enabled
if self._wait_between_requests:
self._last_request_time = time.time()
self._last_request_time = time.monotonic()
return resp.status, response_data

View File

@ -300,7 +300,9 @@ class KlapTransport(BaseTransport):
# There is a 24 hour timeout on the session cookie
# but the clock on the device is not always accurate
# so we set the expiry to 24 hours from now minus a buffer
self._session_expire_at = time.time() + timeout - SESSION_EXPIRE_BUFFER_SECONDS
self._session_expire_at = (
time.monotonic() + timeout - SESSION_EXPIRE_BUFFER_SECONDS
)
self._encryption_session = await self.perform_handshake2(
local_seed, remote_seed, auth_hash
)
@ -312,7 +314,7 @@ class KlapTransport(BaseTransport):
"""Return true if session has expired."""
return (
self._session_expire_at is None
or self._session_expire_at - time.time() <= 0
or self._session_expire_at - time.monotonic() <= 0
)
async def send(self, request: str):

View File

@ -159,7 +159,7 @@ class SmartDevice(Device):
raise AuthenticationError("Tapo plug requires authentication.")
first_update = self._last_update_time is None
now = time.time()
now = time.monotonic()
self._last_update_time = now
if first_update:

View File

@ -392,7 +392,7 @@ class SnowflakeId:
)
def _current_millis(self):
return round(time.time() * 1000)
return round(time.monotonic() * 1000)
def _wait_next_millis(self, last_timestamp):
timestamp = self._current_millis()

View File

@ -224,7 +224,7 @@ async def test_update_module_update_delays(
new_dev = SmartDevice("127.0.0.1", protocol=dev.protocol)
await new_dev.update()
first_update_time = time.time()
first_update_time = time.monotonic()
assert new_dev._last_update_time == first_update_time
for module in new_dev.modules.values():
if module.query():
@ -236,7 +236,7 @@ async def test_update_module_update_delays(
seconds += tick
freezer.tick(tick)
now = time.time()
now = time.monotonic()
await new_dev.update()
for module in new_dev.modules.values():
mod_delay = module.MINIMUM_UPDATE_INTERVAL_SECS