Skip to content

[Backend] Implement Redis Pub/Sub for Distributed Multi-Instance SSE Broadcasting #1188

Description

@blurbeast

Overview & Background

FlowFi delivers real-time stream status and balance updates to connected web clients via Server-Sent Events (SSE) implemented in backend/src/services/sse.service.ts.

Currently, SSEService stores client connections in an in-memory Set<Response>. In a production deployment with multiple backend instances behind a load balancer (e.g. Render, AWS ECS, or Kubernetes), an event processed by the indexer on Instance A is only broadcast to clients connected to Instance A. Clients connected to Instance B miss the live update.


Detailed Problem Statement

  • Multi-container scaling breaks real-time updates for frontend users.
  • Without a shared pub/sub message bus, horizontal scaling of backend API instances is impossible.

Technical Specification & Architecture

1. Redis Pub/Sub Architecture

[Soroban Indexer] 
       │
       ▼
[Publish: flowfi:stream-events] ──► (Redis Cluster)
                                         │
                 ┌───────────────────────┴───────────────────────┐
                 ▼                                               ▼
         [Backend Node A]                                [Backend Node B]
                 │                                               │
         [Local SSE Clients]                             [Local SSE Clients]

2. Implementation in backend/src/services/sse.service.ts

  1. Import Redis publisher and subscriber clients from backend/src/lib/redis.ts.
  2. When sseService.broadcast(event) is called:
    • Serialize event payload to JSON.
    • Publish to channel flowfi:events:broadcast.
  3. In subscriber initialization:
    • Subscribe to flowfi:events:broadcast.
    • On incoming message, parse payload and dispatch to local clients Set.
  4. Resilience & Fallback:
    • If Redis is disconnected or unconfigured in development (REDIS_ENABLED=false), gracefully fall back to local in-memory broadcasting.

Target Files

  • backend/src/services/sse.service.ts
  • backend/src/lib/redis.ts
  • backend/src/controllers/sse.controller.ts
  • backend/tests/unit/sse.service.test.ts

Acceptance Criteria

  • Events published on Node A are received and sent to SSE clients connected to Node B via Redis Pub/Sub.
  • Graceful fallback to local in-memory broadcast if Redis is offline.
  • Heartbeat / keep-alive pings continue to maintain active connections every 15s.
  • Integration tests verify multi-subscriber message delivery.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions