Make live state reliable
Handle order and duplicates
Use stable event identifiers and idempotent application so retries do not corrupt state.
Networks retry. Tabs reconnect. Proxies buffer. The same incident.updated frame can arrive twice, and an older frame can arrive after a newer one.
Application state must not depend on perfect once-only delivery.
Stable ids and monotonic versions
Every event carries evt_84 and a payload version for incident 42:
function applyIncidentUpdated(event) {
const current = incidents.get(event.incidentId)
if (seenEvents.has(event.id)) {
return 'duplicate'
}
if (current && event.payload.version <= current.version) {
return 'stale'
}
seenEvents.add(event.id)
incidents.set(event.incidentId, {
...event.payload,
version: event.payload.version,
})
return 'applied'
}
Applying incident.updated for evt_84 twice leaves the board unchanged the second time. Replaying an older version after a newer one returns stale and must not roll the UI back.
Idempotent commands
Operators retry POSTs and WebSocket commands when acks go missing. Use a command id the server remembers:
async function ackIncident(commandId, incidentId) {
if (processedCommands.has(commandId)) {
return { status: 'already_applied', commandId }
}
await db.markAcknowledged(incidentId)
processedCommands.add(commandId)
return { status: 'applied', commandId }
}
Send the same cmd_91 twice. The database row should flip once; the second call answers already_applied.
Test with replay
Write two tests: duplicate event, then stale event. Assert the visible status string never regresses from resolved to investigating.
Visible proof on the board
Log what happened so tests are obvious:
const result = applyIncidentUpdated(event)
console.log(event.id, result)
// evt_84 applied
// evt_84 duplicate
// evt_80 stale
Your UI code should only repaint when the result is applied. Treat duplicate and stale as success, not errors, because they are normal on real networks.
If you mutate React state with a spread on every message, duplicates may still cause flicker even when data is correct. Gate renders the same way you gate writes.
Store lastAppliedVersion per incident id in memory, not only the last seen event id globally. Two incidents interleaving on the wire is normal during outages.
Try this on your own project: replay the same event id twice, then replay an older version, and confirm the rendered board matches a manual snapshot.
Lesson completed