From e16f3f087534c3f21b3fb97f39dcd7803ca0f79b Mon Sep 17 00:00:00 2001 From: Sahas Subramanian Date: Mon, 16 Jun 2025 13:52:11 +0200 Subject: [PATCH 1/3] Support clearing the latest value in the `LatestValueCache` This can be the overall latest value or the latest value for a specific key. This can be used to clean up old keys for which no further messages are expected. Signed-off-by: Sahas Subramanian --- src/frequenz/channels/_latest_value_cache.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/frequenz/channels/_latest_value_cache.py b/src/frequenz/channels/_latest_value_cache.py index a9ddd364..fe31556b 100644 --- a/src/frequenz/channels/_latest_value_cache.py +++ b/src/frequenz/channels/_latest_value_cache.py @@ -194,6 +194,22 @@ def has_value(self, key: HashableT | Sentinel = NO_KEY) -> bool: return key in self._latest_value_by_key return not isinstance(self._latest_value, Sentinel) + def clear(self, key: HashableT | Sentinel = NO_KEY) -> None: + """Clear the latest value or the latest value for a specific key. + + If `key` is provided, it clears the latest value for that key. If no key is + provided, it clears the latest value received overall. + + Args: + key: An optional key to clear the latest value for that key. If not + provided, it clears the latest value received overall. + """ + if not isinstance(key, Sentinel): + _ = self._latest_value_by_key.pop(key, None) + return + + self._latest_value = NO_VALUE_RECEIVED + async def _run(self) -> None: async for value in self._receiver: self._latest_value = value From 9fcfc1ad99dfe12d31a606797d93b1e02ce67c2c Mon Sep 17 00:00:00 2001 From: Sahas Subramanian Date: Mon, 16 Jun 2025 14:24:37 +0200 Subject: [PATCH 2/3] Add tests for `LatestValueCache.clear()` Signed-off-by: Sahas Subramanian --- tests/test_latest_value_cache_integration.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_latest_value_cache_integration.py b/tests/test_latest_value_cache_integration.py index 46cef2c4..7c4e8b5e 100644 --- a/tests/test_latest_value_cache_integration.py +++ b/tests/test_latest_value_cache_integration.py @@ -100,3 +100,18 @@ async def test_latest_value_cache_key() -> None: assert cache.get(6) == (6, "g") assert cache.keys() == {5, 6, 12} + + cache.clear() + assert not cache.has_value() + + assert cache.keys() == {5, 6, 12} + assert cache.has_value(5) + assert cache.get(5) == (5, "c") + + cache.clear(5) + assert not cache.has_value(5) + assert cache.has_value(6) + + with pytest.raises(ValueError, match="No value received for key: 5"): + assert cache.get(5) + assert cache.keys() == {6, 12} From fbbf48cf1308cadd1187bbd237345485753086c2 Mon Sep 17 00:00:00 2001 From: Sahas Subramanian Date: Mon, 16 Jun 2025 14:37:14 +0200 Subject: [PATCH 3/3] Update release notes Signed-off-by: Sahas Subramanian --- RELEASE_NOTES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 52636b7c..735ce385 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -12,6 +12,8 @@ - `LatestValueCache` now takes an optional `key` function, which returns the key for each incoming message, and the latest value for each key is cached and can be retrieved separately. +- `LatestValueCache` got a new `clear` method that clears the latest value. When an optional `key` argument is specified, it clears the value only for that key. + ## Bug Fixes