-
Notifications
You must be signed in to change notification settings - Fork 341
Description
The EmbeddedChatApi class fails to clear existing message event listeners when the connect() method is called. The issue occurs because rcClient.onMessage(...) is additive: every invocation registers a new callback without removing previously registered ones.
The close() method currently calls unsubscribeAll() on the SDK client, but this only unsubscribes from server-side DDP streams. It does not clear the internal JavaScript callbacks registered via onMessage on the client instance.
As a result, each reconnect accumulates additional message listeners.
UI Masking
This issue is largely hidden in the UI due to message deduplication logic:
- The React frontend uses a store that deduplicates messages by ID.
useMessageStorerelies on anupsertMessagehelper that updates existing messages if the ID already exists.
Effect:
- Duplicate message events are processed internally.
- The UI shows only a single message update, masking the underlying duplication.
Memory Leak (Linear Growth)
- Each reconnection adds a new closure retaining references to the message handler context.
- Long-lived sessions or unstable network conditions cause unbounded listener growth
Performance Degradation
- CPU Overhead: Each incoming message triggers the processing logic N times.
- Render Thrashing: Even with deduplication, repeated state updates may still trigger reconciliation cycles depending on equality checks.
Side-Effect Duplication
Any non-idempotent side effects tied to message receipt will execute multiple times:
- Sound notifications
- Read receipts
- Analytics or logging
- Desktop notifications
Example: After 5 reconnects, a single incoming message may trigger 5 notification sounds.
Reproduction
- Login and connect.
- Send Message 1 → Received once.
- Reconnect (simulate network flap).
- Send Message 2 → Received twice (proof of leak).
Expected behaviour
Ensure message listeners are registered exactly once, or explicitly removed before adding new ones during reconnection.