Symptom

A node that fires twice in under one second leaves clients showing stale state (stuck at NONE) after the second fire. The UI lights up for the first fire but silently ignores the second.

Root cause

Two independent 1-second debounce layers in the server’s event pipeline both suppressed the second fire:

  1. ServerNodeManager.update() timestamp guard — the condition node.timestamp - origin.timestamp > 1000 prevented posting STATE_CHANGE events when consecutive writes happened within 1 second of each other. Since EventClient (shared/) connects to /events and updates ClientNodeManager exclusively via STATE_CHANGE events, rapid transitions were silently dropped.

  2. EventTracker.dbounce() payload-blind comparison — even if the guard in update() was absent, EventTracker.dbounce() checked only event.type (not the payload’s target state) within a 1-second window. Two STATE_CHANGE events for the same node with different states (e.g. EXECUTEDWARN) were incorrectly treated as duplicates and the second was suppressed. Critically, processedEvents was never cleared on NONE settle, so a NONE → EXECUTED → NONE → EXECUTED sequence left the second EXECUTED matching the first in the dedup map.

Fix

Prevention