fix(celery): write display_power value and TTL atomically

- a soft-limit signal between SET and EXPIRE could leave display_power
  without a TTL (stale value that never expires)
- use a single SET with ex= so the write and TTL are atomic

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Viktor Petersson
2026-06-11 09:55:20 +00:00
parent c1c89a75e5
commit f5e9466427
2 changed files with 9 additions and 4 deletions

View File

@@ -318,8 +318,11 @@ def get_display_power() -> None:
# — and the on/off state now actually populates instead of only
# the error cases ever landing.
try:
r.set('display_power', str(diagnostics.get_display_power()))
r.expire('display_power', 3600)
# Single SET with ex= so the value and its TTL are written
# atomically — a soft-limit signal landing between a separate
# SET and EXPIRE would otherwise leave the key without a TTL
# (a stale display_power that never expires).
r.set('display_power', str(diagnostics.get_display_power()), ex=3600)
except SoftTimeLimitExceeded:
# The CEC query is meant to be bounded by its own
# subprocess timeout, but a child wedged in libcec can keep

View File

@@ -194,11 +194,13 @@ def test_get_display_power_writes_redis_as_str(
):
get_display_power.apply()
fake_redis.set.assert_called_once_with('display_power', expected)
# Value and TTL are written atomically in a single SET (ex=) so a
# soft-limit signal can't leave the key without a TTL.
fake_redis.set.assert_called_once_with('display_power', expected, ex=3600)
fake_redis.expire.assert_not_called()
# No bool ever reaches redis — guards against the DataError.
written = fake_redis.set.call_args.args[1]
assert isinstance(written, str)
fake_redis.expire.assert_called_once_with('display_power', 3600)
def test_send_telemetry_task_dispatches() -> None: