Skip to content

feat(collaboration): add Redis-backed Socket.IO session adapter - #1091

Merged
RUKAYAT-CODER merged 2 commits into
rinafcode:mainfrom
JemimahEkong:feat/collaboration-redis-adapter
Jul 26, 2026
Merged

feat(collaboration): add Redis-backed Socket.IO session adapter#1091
RUKAYAT-CODER merged 2 commits into
rinafcode:mainfrom
JemimahEkong:feat/collaboration-redis-adapter

Conversation

@JemimahEkong

Copy link
Copy Markdown
Contributor

Summary

Closes #817

This PR replaces the collaboration module's in-memory WebSocket state with Redis-backed infrastructure, enabling reliable horizontal scaling across multiple Node.js instances while preserving existing Socket.IO behavior.

Previously, each application instance maintained isolated socket rooms and presence state, meaning users connected to different pods could not reliably receive collaboration updates or see accurate presence information.

What Changed

Socket.IO Redis Adapter

Updated src/main.ts to integrate @socket.io/redis-adapter:

  • Added Redis pub/sub clients for Socket.IO cross-instance communication
  • Enabled room broadcasts across multiple pods/instances
  • Preserved existing transport limits including maxHttpBufferSize
  • Added graceful fallback to the default in-memory adapter when Redis is unavailable

Redis Socket Registry

Added:

src/collaboration/redis-socket-registry.service.ts

Responsibilities:

  • Stores socket ownership metadata in Redis

  • Maps:

    • socketId → sessionId
    • socketId → userId
  • Uses Redis hash storage:
    collab:socket:{socketId}

TTL behavior:

  • 24-hour TTL while the socket is active
  • 30-second grace period after disconnect to support reconnect flows without presence flickering

Redis-Backed Presence Service (src/collaboration/presence.service.ts)

Migrated presence tracking from local memory to Redis hashes.

Changes:

  • Removed in-memory nested Map storage

  • Added Redis-backed operations using:
    HSET
    HDEL
    HGETALL
    HEXISTS

  • Updated presence methods to async operations

  • Enabled shared presence state across all application instances

This ensures users connected to different pods receive accurate membership updates.

Collaboration Gateway Updates (src/collaboration/collaboration.gateway.ts)

Updated gateway logic to use Redis-backed state.

Changes:

  • Replaced local socketMap with RedisSocketRegistryService
  • Added OnGatewayConnection lifecycle handling
  • Updated join and disconnect handlers to await Redis operations
  • Preserved existing room broadcasting behavior
  • Enabled cross-pod event delivery through Socket.IO Redis adapter

Redis Data Model

Key Type Purpose
collab:socket:{socketId} Hash Stores socket session and user mapping
collab:presence:{sessionId} Hash Stores session participant presence

Why This Change

The previous collaboration architecture relied on process-local memory.

This caused issues for horizontally scaled deployments:

  • Each pod had isolated Socket.IO rooms
  • Presence state was not shared between instances
  • Users connected to different pods could not reliably receive collaboration updates

Redis-backed state provides a shared source of truth and allows the collaboration module to scale across multiple backend instances.

Testing

Validated with:

✅ 78 tests passing across 7 collaboration spec files

New and updated coverage includes:

  • Gateway join flows
  • Disconnect handling
  • Reconnection behavior
  • Cross-pod broadcast scenarios
  • Redis socket registry behavior
  • Redis-backed presence operations

Additional checks:

✅ Lint: 0 errors, 0 warnings

Build:

✅ No build issues introduced by this change

Note:

  • Existing @redis/time-series type issue in the base branch remains unrelated to this PR.

Limitations

  • Redis is required in production for multi-instance collaboration deployments
  • Single-process development continues to work through graceful fallback behavior
  • OT/CRDT revision counters remain in-memory and are outside the scope of this issue
  • Change history persistence remains unchanged
  • Unexpected client crashes may temporarily leave stale presence data until cleanup occurs

Reviewer Notes

This PR introduces distributed collaboration infrastructure while keeping existing collaboration behavior unchanged.

Redis responsibilities are isolated into dedicated services, making the system easier to scale and providing a clean foundation for future persistence improvements.

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Well done on the job so far!
Kindly resolve conflict

@drips-wave

drips-wave Bot commented Jul 26, 2026

Copy link
Copy Markdown

@JemimahEkong Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@JemimahEkong

JemimahEkong commented Jul 26, 2026 via email

Copy link
Copy Markdown
Contributor Author

@RUKAYAT-CODER

Copy link
Copy Markdown
Contributor

Thank you for contributing to the project.

@RUKAYAT-CODER
RUKAYAT-CODER merged commit 40cd4b0 into rinafcode:main Jul 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CollaborationGateway stores socket-to-session mapping in process memory

2 participants