|
296 | 296 |
|
297 | 297 | --- |
298 | 298 |
|
| 299 | +## 🔄 Session Resilience & Host Disconnection |
| 300 | + |
| 301 | +> **Principle:** A room is a durable object. A host is just a role. |
| 302 | +
|
| 303 | +### Room-Centric Architecture |
| 304 | + |
| 305 | +- [ ] **Persistent Room Model** |
| 306 | + - [ ] Decouple room lifecycle from host connection |
| 307 | + - [ ] Room survives host disconnects (status: `open | active | paused | closed`) |
| 308 | + - [ ] Add `current_host_id` field (nullable) to sessions table |
| 309 | + - [ ] Implement room TTL expiration (configurable, e.g., 24h inactive) |
| 310 | + - [ ] Room only closes via explicit action or TTL expiration |
| 311 | + |
| 312 | +- [ ] **Media Sessions (Ephemeral)** |
| 313 | + - [ ] Create `media_sessions` table (separate from rooms) |
| 314 | + - [ ] Track media session properties: `id`, `room_id`, `mode`, `publisher_id`, `status` |
| 315 | + - [ ] Media session states: `active | paused | ended` |
| 316 | + - [ ] End/pause media session when host disconnects (room stays alive) |
| 317 | + - [ ] Allow new media session to attach when host reconnects or transfers |
| 318 | + |
| 319 | +### Host Disconnection Handling |
| 320 | + |
| 321 | +- [ ] **Immediate Behavior** |
| 322 | + - [ ] Room remains open on host disconnect |
| 323 | + - [ ] Viewers stay connected to UI, chat, presence, SFU (if applicable) |
| 324 | + - [ ] Screen share pauses/freezes gracefully (last frame or placeholder) |
| 325 | + - [ ] No automatic participant kick |
| 326 | + |
| 327 | +- [ ] **UX Messaging** |
| 328 | + - [ ] "Host disconnected. Waiting for reconnection…" overlay |
| 329 | + - [ ] Countdown timer or reconnection status indicator |
| 330 | + - [ ] Clear visual state for "host offline" |
| 331 | + - [ ] Only hard-kick when room is explicitly closed |
| 332 | + |
| 333 | +### Reconnection Logic |
| 334 | + |
| 335 | +- [ ] **Grace Period** |
| 336 | + - [ ] Implement host reconnection window (2-5 minutes configurable) |
| 337 | + - [ ] Auto-reattach returning host (no participant disruption) |
| 338 | + - [ ] Resume screen sharing on host reconnect |
| 339 | + - [ ] ICE restart for P2P connections on reconnect |
| 340 | + |
| 341 | +- [ ] **Host Reassignment (if host doesn't return)** |
| 342 | + - [ ] Option A: Admin/host can pre-designate backup host |
| 343 | + - [ ] Option B: Auto-promote a controller to host role |
| 344 | + - [ ] Option C: Viewer-only continuation (room stays alive, no screen share) |
| 345 | + - [ ] New host can start fresh screen sharing session |
| 346 | + |
| 347 | +### Presence & Heartbeats |
| 348 | + |
| 349 | +- [ ] **Client Heartbeats** |
| 350 | + - [ ] Periodic heartbeat from all clients (every 30s) |
| 351 | + - [ ] Soft-state presence (disconnection inferred, not immediate) |
| 352 | + - [ ] Grace period before marking participant offline |
| 353 | + - [ ] Avoid false "everyone dropped" on brief network blips |
| 354 | + |
| 355 | +- [ ] **Host Status Tracking** |
| 356 | + - [ ] Track `host_last_seen_at` timestamp |
| 357 | + - [ ] Distinguish between "host offline" vs "host left intentionally" |
| 358 | + - [ ] Broadcast host status changes to all participants |
| 359 | + |
| 360 | +### SFU vs P2P Behavior |
| 361 | + |
| 362 | +- [ ] **P2P Mode** |
| 363 | + - [ ] Media streams drop on host disconnect |
| 364 | + - [ ] Room stays alive for chat/presence |
| 365 | + - [ ] Reconnect requires SDP renegotiation |
| 366 | + - [ ] Participants not kicked |
| 367 | + |
| 368 | +- [ ] **SFU Mode (Better UX)** |
| 369 | + - [ ] SFU keeps viewer connections alive |
| 370 | + - [ ] Viewers see last frame or placeholder |
| 371 | + - [ ] New publisher can attach seamlessly |
| 372 | + - [ ] No participant connection disruption |
| 373 | + |
| 374 | +--- |
| 375 | + |
299 | 376 | ## 📦 Distribution |
300 | 377 |
|
301 | 378 | - [ ] **Build Pipeline** |
|
0 commit comments