Skip to content

Conversation

@cj-vana
Copy link
Collaborator

@cj-vana cj-vana commented Oct 10, 2025

User description

Resolves persistent WebSocket connection failures with robust reconnection logic.

Changes:

  • Add useRealtimeSubscription hook with exponential backoff retry strategy
    • Configurable retry attempts (default: 10) and delays (1s → 30s max)
    • Proper channel cleanup before reconnect attempts
    • Jitter to prevent thundering herd problem
  • Update SharedShowModePage to use new hook instead of manual subscription
  • Add real-time connection status indicator UI:
    • Live (green) - Connected and receiving updates
    • Connecting (blue) - Initial connection attempt
    • Reconnecting (yellow) - Auto-retry in progress with attempt count
    • Offline (gray) - Disconnected
    • Connection failed (red) - Max retries exceeded with manual retry button

Before: WebSocket fails → terminal error → manual page refresh required
After: WebSocket fails → automatic reconnection with visual feedback

🤖 Generated with Claude Code


PR Type

Bug fix, Enhancement


Description

  • Add robust WebSocket reconnection with exponential backoff

  • Replace manual subscription with reusable hook

  • Add real-time connection status indicator

  • Implement automatic retry with visual feedback


Diagram Walkthrough

flowchart LR
  A["Manual WebSocket"] --> B["useRealtimeSubscription Hook"]
  B --> C["Exponential Backoff"]
  B --> D["Connection Status UI"]
  C --> E["Auto Reconnection"]
  D --> F["Visual Feedback"]
Loading

File Walkthrough

Relevant files
Enhancement
useRealtimeSubscription.ts
Add robust real-time subscription hook                                     

apps/web/src/hooks/useRealtimeSubscription.ts

  • Create reusable hook for Supabase real-time subscriptions
  • Implement exponential backoff retry strategy with jitter
  • Add connection status tracking and error handling
  • Include proper cleanup and channel management
+249/-0 
Bug fix
SharedShowModePage.tsx
Integrate reconnection hook and status UI                               

apps/web/src/pages/SharedShowModePage.tsx

  • Replace manual WebSocket subscription with new hook
  • Add connection status indicator UI with color coding
  • Implement retry button for failed connections
  • Update imports for new icons and hook
+75/-48 

Resolves persistent WebSocket connection failures with robust reconnection logic.

Changes:
- Add useRealtimeSubscription hook with exponential backoff retry strategy
  - Configurable retry attempts (default: 10) and delays (1s → 30s max)
  - Proper channel cleanup before reconnect attempts
  - Jitter to prevent thundering herd problem
- Update SharedShowModePage to use new hook instead of manual subscription
- Add real-time connection status indicator UI:
  - Live (green) - Connected and receiving updates
  - Connecting (blue) - Initial connection attempt
  - Reconnecting (yellow) - Auto-retry in progress with attempt count
  - Offline (gray) - Disconnected
  - Connection failed (red) - Max retries exceeded with manual retry button

Before: WebSocket fails → terminal error → manual page refresh required
After: WebSocket fails → automatic reconnection with visual feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@netlify
Copy link

netlify bot commented Oct 10, 2025

Deploy Preview for sounddocsbeta ready!

Name Link
🔨 Latest commit 977c101
🔍 Latest deploy log https://app.netlify.com/projects/sounddocsbeta/deploys/68e9555b94c7d70008a6bcdd
😎 Deploy Preview https://deploy-preview-114--sounddocsbeta.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@qodo-code-review
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 10, 2025

CI Feedback 🧐

(Feedback updated until commit 977c101)

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: pr-checks-summary

Failed stage: Summary [❌]

Failure summary:

The workflow step "PR Checks Summary" intentionally failed because the TypeScript checks were marked
as failed:
- In the shell script, if [ "failure" == "success" ] evaluated to false, so it echoed
TypeScript checks: FAILED.
- The overall status logic checked [ "failure" == "failure" ] and exited
with code 1, producing Overall Status: FAILED.
- Python and SQL checks were not run due to no
file changes and did not affect the failure.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

22:  Secret source: Actions
23:  Prepare workflow directory
24:  Prepare all required actions
25:  Complete job name: pr-checks-summary
26:  ##[group]Run echo "## PR Checks Summary"
27:  �[36;1mecho "## PR Checks Summary"�[0m
28:  �[36;1mecho ""�[0m
29:  �[36;1m�[0m
30:  �[36;1m# Check TypeScript�[0m
31:  �[36;1mif [ "true" == "true" ]; then�[0m
32:  �[36;1m  if [ "failure" == "success" ]; then�[0m
33:  �[36;1m    echo "✅ TypeScript checks: PASSED"�[0m
34:  �[36;1m  elif [ "failure" == "skipped" ]; then�[0m
35:  �[36;1m    echo "⏭️  TypeScript checks: SKIPPED (no changes)"�[0m
36:  �[36;1m  else�[0m
37:  �[36;1m    echo "❌ TypeScript checks: FAILED"�[0m
38:  �[36;1m  fi�[0m
39:  �[36;1melse�[0m
40:  �[36;1m  echo "⏭️  TypeScript checks: No files changed"�[0m
41:  �[36;1mfi�[0m
42:  �[36;1m�[0m
43:  �[36;1m# Check Python�[0m
44:  �[36;1mif [ "false" == "true" ]; then�[0m
45:  �[36;1m  if [ "skipped" == "success" ]; then�[0m
46:  �[36;1m    echo "✅ Python checks: PASSED"�[0m
47:  �[36;1m  elif [ "skipped" == "skipped" ]; then�[0m
48:  �[36;1m    echo "⏭️  Python checks: SKIPPED (no changes)"�[0m
49:  �[36;1m  else�[0m
50:  �[36;1m    echo "❌ Python checks: FAILED"�[0m
51:  �[36;1m  fi�[0m
52:  �[36;1melse�[0m
53:  �[36;1m  echo "⏭️  Python checks: No files changed"�[0m
54:  �[36;1mfi�[0m
55:  �[36;1m�[0m
56:  �[36;1m# Check SQL�[0m
57:  �[36;1mif [ "false" == "true" ]; then�[0m
58:  �[36;1m  if [ "skipped" == "success" ]; then�[0m
59:  �[36;1m    echo "✅ SQL checks: PASSED"�[0m
60:  �[36;1m  elif [ "skipped" == "skipped" ]; then�[0m
61:  �[36;1m    echo "⏭️  SQL checks: SKIPPED (no changes)"�[0m
62:  �[36;1m  else�[0m
63:  �[36;1m    echo "❌ SQL checks: FAILED"�[0m
64:  �[36;1m  fi�[0m
65:  �[36;1melse�[0m
66:  �[36;1m  echo "⏭️  SQL checks: No files changed"�[0m
67:  �[36;1mfi�[0m
68:  �[36;1m�[0m
69:  �[36;1m# Overall status�[0m
70:  �[36;1mecho ""�[0m
71:  �[36;1mif [ "failure" == "failure" ] || \�[0m
72:  �[36;1m   [ "skipped" == "failure" ] || \�[0m
73:  �[36;1m   [ "skipped" == "failure" ]; then�[0m
74:  �[36;1m  echo "❌ **Overall Status: FAILED**"�[0m
75:  �[36;1m  echo "Please fix the issues above before merging."�[0m
76:  �[36;1m  exit 1�[0m
77:  �[36;1melse�[0m
78:  �[36;1m  echo "✅ **Overall Status: PASSED**"�[0m
79:  �[36;1m  echo "All checks on changed files have passed!"�[0m
80:  �[36;1mfi�[0m
81:  shell: /usr/bin/bash -e {0}
82:  ##[endgroup]
83:  ## PR Checks Summary
84:  ❌ TypeScript checks: FAILED
85:  ⏭️  Python checks: No files changed
86:  ⏭️  SQL checks: No files changed
87:  ❌ **Overall Status: FAILED**
88:  Please fix the issues above before merging.
89:  ##[error]Process completed with exit code 1.
90:  Cleaning up orphan processes

@qodo-code-review
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Use a deterministic channel name

Use a deterministic channel name for Supabase subscriptions by removing
Date.now(). This ensures the same channel is reused across reconnections,
improving efficiency.

apps/web/src/hooks/useRealtimeSubscription.ts [152-154]

-// Create channel with unique name
-const channelName = `public:${table}${filter ? `:${filter}` : ""}:${Date.now()}`;
+// Create channel with a deterministic name
+const channelName = `realtime:public:${table}${filter ? `:${filter}` : ""}`;
 const channel = supabase.channel(channelName);
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a significant issue where using Date.now() in the channel name prevents channel reuse, leading to inefficiency and potential resource leaks on every reconnection.

Medium
  • More

@cj-vana cj-vana merged commit 8978c20 into beta Oct 10, 2025
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant