From 4edd5b7866a0ca550437fb966f90fb4674f48276 Mon Sep 17 00:00:00 2001 From: JayChickenK <19538983+JayChickenK@users.noreply.github.com> Date: Wed, 19 Aug 2026 22:22:11 +0200 Subject: [PATCH] observe: assign fallback_hrefs under the notify lock on_notification discards on the DTLS reader thread. Snapshotting _notified then assigning fallback_hrefs after releasing the lock let a notify in that window land on the set object being replaced, so a just-pushed href was classified silent until its next notify. --- custom_components/localthings/observe.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_components/localthings/observe.py b/custom_components/localthings/observe.py index ec1142c..610f468 100644 --- a/custom_components/localthings/observe.py +++ b/custom_components/localthings/observe.py @@ -96,7 +96,8 @@ class ObserveManager: self._last_notify_ts: float | None = None # Wakes try_enter_observe_mode's grace wait early once enough hrefs # have notified. Guards `_notified` mutations, the `wait_for`, and - # fallback_hrefs discards from on_notification. + # fallback_hrefs (enter_observe_mode assignment, on_notification + # discard). self._notify_cond = threading.Condition() # Idle while polling, except after downgrade_to_poll (every href # that was subscribed). While in observe mode this is the set of @@ -280,14 +281,13 @@ class ObserveManager: #294) -- committing against a session a reconnect already replaced would claim observe mode with nothing left to notice it's dead.""" self.subscribed_hrefs = set(subscribed) - with self._notify_cond: - notified = set(self._notified) # Issue #92: subscribed-but-silent hrefs are counted as covered by # push if we drop this, but they never emit a notify. Keep them on # the poll cadence via fallback_hrefs (otherwise idle in observe). - # This is the 80% quorum snapshot; a later notify discards the - # href in on_notification. - self.fallback_hrefs = set(subscribed) - notified + # Same lock as on_notification's discard so a notify in this window + # cannot land on a set object that is about to be replaced. + with self._notify_cond: + self.fallback_hrefs = set(subscribed) - self._notified self._set_mode(MODE_OBSERVE) self.start_refresh_task(session)