fix(display): a failed on-demand request drops the session it ended (#779)

_set_on_demand_error ends any running session (_reset_on_demand_fields)
but left its saved copy, display_on_demand_config, in the cache. A failed
request that replaced a running session therefore made the next restart
resume the session that had already ended.

Clear the saved copy where every error path goes through, and drop the
two restore-failed callers' own clears, which this now covers.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-10-09 12:05:22 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 1bcb524fc3
commit 20bae8b609
3 changed files with 23 additions and 3 deletions
+7
View File
@@ -168,6 +168,13 @@ plugin-facing methods only get `@deprecated` (see below).
- Unused pins dropped: `markupsafe` (Flask still installs it) and
`pytest-mock`.
### Fixes
- A failed on-demand request no longer comes back after a restart as the
session it ended. A failed request ends any running session, but the
saved copy of that session (`display_on_demand_config`) was left behind,
so the next restart of the display resumed it.
## 3.8.2
The display hands freed memory back to the OS (#774), and sports consolidation
+7 -3
View File
@@ -655,7 +655,6 @@ class DisplayController:
except Exception: # pylint: disable=broad-except
cached_session = None
if self.on_demand_active or cached_session:
self.cache_manager.clear_cache('display_on_demand_config')
self._set_on_demand_error('restore-failed')
# Its state machine no longer describes what runs; let the last
# snapshot go stale (readers then say unknown) rather than keep
@@ -1804,8 +1803,14 @@ class DisplayController:
logger.error("Failed to publish on-demand state: %s", err, exc_info=True)
def _set_on_demand_error(self, message: str) -> None:
"""Set on-demand state to error and publish."""
"""Set on-demand state to error and publish.
Ends any running session, so its saved copy goes too: a failed
request that replaced a session left display_on_demand_config
behind, and the next restart resumed the session that had ended.
"""
self._reset_on_demand_fields()
self.cache_manager.clear_cache('display_on_demand_config')
self.on_demand_status = 'error'
self.on_demand_last_error = message
self.on_demand_last_event = None
@@ -2743,7 +2748,6 @@ class DisplayController:
logger.error("On-demand session for plugin '%s' cannot resume after the "
"restart: the plugin has no loaded display modes (did it "
"fail to load?); ending it", plugin_id)
self.cache_manager.clear_cache('display_on_demand_config')
self._set_on_demand_error('restore-failed')
return
+9
View File
@@ -217,6 +217,15 @@ class TestReleasingThePlugin:
assert controller.current_display_mode == 'clock'
assert controller.force_change is True
def test_a_failed_request_that_ends_the_session_drops_its_saved_copy(self, controller):
"""Otherwise the next restart resumes the session that just ended."""
_start(controller, plugin_id='clock')
controller.cache_manager.clear_cache.reset_mock()
_start(controller, plugin_id='uninstalled')
controller.cache_manager.clear_cache.assert_called_once_with('display_on_demand_config')
def test_a_plugin_enabled_during_the_session_stays_loaded(self, controller):
_start(controller)
controller.test_config['preview-me'] = {'enabled': True}