Skip to content

feat(mqtt): historical replay from MongoDB via Last-Event-ID #606

Description

@mkjsix

Sub-issue of #601.

Summary

When an SSE client reconnects after a disconnect and sends a Last-Event-ID header, replay the missed events from MongoDB before switching to the live MQTT stream.

Motivation

SSE's Last-Event-ID mechanism is designed for exactly this use case. Without replay, a client that disconnects for 30 seconds during a burst of sensor events simply loses those readings. With replay, the client catches up seamlessly — critical for applications that need a complete time-series record.

Proposed behaviour

  1. Client connects: GET /mqtt-sse?topic=sensors/%23 with header Last-Event-ID: <objectId>.
  2. MqttSseService queries MongoDB for documents in the matching collection(s) where _id > lastEventId, ordered by receivedAt ascending.
  3. Historical documents are streamed as SSE events first.
  4. Once historical replay is exhausted, the connection seamlessly switches to the live MQTT fanout.
  5. If mqtt-mongo-writer is not enabled, Last-Event-ID is silently ignored and the client receives only the live stream (graceful degradation).

Scope

  • MqttSseService detects lastEventId parameter in onConnect.
  • Replay query uses the same mongo-sink mapping from mqtt-mongo-writer config to find the target collection.
  • Replay runs on a virtual thread; live messages are buffered in the per-connection queue during replay to prevent gaps at the handover point.
  • Configurable max-replay-messages to cap the replay size for very long disconnects.
  • Integration test: publish 100 messages, disconnect, publish 50 more, reconnect with Last-Event-ID, assert all 50 missed messages are replayed before live stream resumes.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions