From 6f1c4dae36275e6b268f054dfd7768e9a4d69efe Mon Sep 17 00:00:00 2001 From: Peter Holloway Date: Fri, 24 Apr 2026 11:03:19 +0100 Subject: [PATCH 1/2] fix: Clear client caches when environment is reloaded --- src/blueapi/client/client.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/blueapi/client/client.py b/src/blueapi/client/client.py index 034b9f6a98..20de158929 100644 --- a/src/blueapi/client/client.py +++ b/src/blueapi/client/client.py @@ -3,6 +3,7 @@ import time from collections.abc import Iterable from concurrent.futures import Future +from contextlib import suppress from functools import cached_property from itertools import chain from pathlib import Path @@ -675,6 +676,11 @@ def reload_environment( """ try: status = self._rest.delete_environment() + # clear the cached plans/devices as they may have changed + with suppress(AttributeError): + del self.plans + with suppress(AttributeError): + del self.devices except ( BlueskyRequestError, ServiceUnavailableError, From 7caf8a94e464bf9207cc767a99c3313a8eefd24e Mon Sep 17 00:00:00 2001 From: Peter Holloway Date: Wed, 24 Jun 2026 14:03:06 +0100 Subject: [PATCH 2/2] Add test for cache clearing --- tests/unit_tests/client/test_client.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/unit_tests/client/test_client.py b/tests/unit_tests/client/test_client.py index 125fc165c2..eaf96a3b2d 100644 --- a/tests/unit_tests/client/test_client.py +++ b/tests/unit_tests/client/test_client.py @@ -292,6 +292,25 @@ def test_reload_environment( assert environment == NEW_ENV +def test_reload_environment_removes_caches(client: BlueapiClient, mock_rest: Mock): + mock_rest.get_environment.return_value = NEW_ENV + + _ = client.plans, client.devices + _ = client.plans, client.devices + + # rest calls only made once as plans/devices are cached + mock_rest.get_plans.assert_called_once() + mock_rest.get_devices.assert_called_once() + mock_rest.reset_mock() + + client.reload_environment() + _ = client.plans, client.devices + + # When environment is reloaded, caches are cleared so another call is required + mock_rest.get_plans.assert_called_once() + mock_rest.get_devices.assert_called_once() + + @patch("blueapi.client.client.time.time") @patch("blueapi.client.client.time.sleep") def test_reload_environment_no_timeout(