From 84940daebf5445f082ba98884f624a18a7c0dfe1 Mon Sep 17 00:00:00 2001 From: Lukas Gomez Date: Tue, 18 Aug 2026 18:25:32 -0400 Subject: [PATCH 1/2] Warn once per missing scene item instead of every tick Every SceneItem action polls get_scene_item_enabled once per tick. When the active scene collection does not contain the referenced scenes (e.g. a lightweight idle collection while the deck page targets the meeting one), each action logged the warning every second: a page with 58 SceneItem actions wrote ~3,500 journal lines per minute for as long as OBS stayed in that collection. Track already-reported (scene, item) pairs and warn once per pair, naming the pair so the message is actionable. --- backend/OBSController.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/OBSController.py b/backend/OBSController.py index 53c647d..a106282 100644 --- a/backend/OBSController.py +++ b/backend/OBSController.py @@ -87,6 +87,11 @@ def __init__(self): self._connected_state = False self.event_obs: obsws = None # All events are connected to this to avoid crash if a request is made in an event self.volume_meters = {} + # (scene, item) pairs already reported missing by get_scene_item_enabled. + # Every SceneItem action polls once per tick, so when the active scene + # collection doesn't contain the referenced scenes an unconditional + # warning floods the journal at one line per action per second. + self._missing_scene_items = set() pass @property @@ -460,7 +465,14 @@ def get_scene_item_enabled(self, sceneName: str, sourceName: str) -> None: return self.call(requests.GetSceneItemEnabled(sceneName=sceneName, sceneItemId=sceneItemId)) except Exception as e: if str(e) == "'sceneItemId'": - log.warning("Cannot find the scene item!") + # Expected while another scene collection is active: warn once + # per pair instead of once per tick. + if (sceneName, sourceName) not in self._missing_scene_items: + self._missing_scene_items.add((sceneName, sourceName)) + log.warning( + f"Cannot find scene item {sourceName!r} in scene " + f"{sceneName!r} -- suppressing repeats of this warning" + ) else: log.error(e) From 0db169edd46aa2628832c63e9c48e55bb94b4e1c Mon Sep 17 00:00:00 2001 From: Lukas Gomez Date: Tue, 18 Aug 2026 18:25:32 -0400 Subject: [PATCH 2/2] Treat an empty filter status as unknown, not indexable show_current_filter_status guarded against None, but the backend returns an empty dict when the scene or filter does not exist in the active scene collection. Indexing it raised a KeyError through the rpyc netref, and loguru dumped a ~65-line traceback on every tick -- one full traceback per second per filter action while another collection was active. Fall into the existing UNKNOWN path instead. --- actions/Filter/FilterBase.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/actions/Filter/FilterBase.py b/actions/Filter/FilterBase.py index df0dd39..2dad4e4 100644 --- a/actions/Filter/FilterBase.py +++ b/actions/Filter/FilterBase.py @@ -42,7 +42,10 @@ def show_current_filter_status(self): return status = self.backend.get_source_filter(self.get_settings().get("scene"), self.get_settings().get("filter")) - if status is None: + # The backend returns an empty dict (not None) when the scene or filter + # doesn't exist in the active scene collection; indexing it raises a + # KeyError over rpyc and logs a full traceback on every tick. + if not status or "filterEnabled" not in status: self.current_state = State.UNKNOWN self.hide_error() self.show_for_state(State.UNKNOWN)