Skip to content

feat(realtime): subscribe retry improvements #747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

grdsdev
Copy link
Collaborator

@grdsdev grdsdev commented Jul 14, 2025

What kind of change does this PR introduce?

#742

What is the current behavior?

Channel doesn't have a limit for retrying, so it keeps retrying indefinitely, which causes a crash due the recursive call.

What is the new behavior?

Add a max retry attempt configuration (default to 5 attempts), along with a backoff + jitter delay calculation for the retry.

  • Add a new method subscribeWithError() which throws a RealtimeError.maxRetryAttemptsReached or a CancellationError.
  • Phase 1 (Current): Deprecate the subscribe() method in favor of the subscribeWithError()
  • Phase 2 (Next Major Release): Rename subscribeWithError() back to subscribe() and remove the withError variant, it means the default will be the throwing method.

Additional context

Add any other context or screenshots.

@coveralls
Copy link

coveralls commented Jul 14, 2025

Pull Request Test Coverage Report for Build 16438495062

Details

  • 99 of 105 (94.29%) changed or added relevant lines in 4 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.3%) to 76.944%

Changes Missing Coverage Covered Lines Changed/Added Lines %
Sources/Realtime/RealtimeChannelV2.swift 94 100 94.0%
Totals Coverage Status
Change from base Build 16421359102: 0.3%
Covered Lines: 5393
Relevant Lines: 7009

💛 - Coveralls

grdsdev added 8 commits July 22, 2025 05:07
- Add missing return statement in subscribeWithError() to prevent infinite retries
- Add heartbeat response handling in testBehavior test
- Fix test expectations for retry attempts
- Ensure proper cleanup on subscription failure

This fixes the issue where successful subscriptions would continue retrying
and tests would fail due to incorrect retry attempt counting.
@grdsdev grdsdev force-pushed the feature/realtime-retry-improvements branch from 4906875 to d702903 Compare July 22, 2025 08:07
@grdsdev grdsdev marked this pull request as ready for review July 22, 2025 08:07
@grdsdev grdsdev requested a review from o-santi July 22, 2025 08:12
logger?.error("Subscribe failed: \(error)")
}
}
_ = await statusChange.first { @Sendable in $0 == .subscribed }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some consideration on what await subscribe() should wait for exactly. @filipecabaco explained that both the broadcast and the presence parts should be considered as subscribed on the message acknoledgement success, which is what is currently being done:

case .system:
if message.status == .ok {
logger?.debug("Subscribed to channel \(message.topic)")
status = .subscribed
} else {
logger?.debug(
"Failed to subscribe to channel \(message.topic): \(message.payload)"
)
}

but the postgres_changes part is only available when it receives the system message saying you're subscribed, which may take some time. This is already the current behavior, but maybe it is worth it adding this distinction in the RealtimeSubscribedStates, as a client may only be subscribed to broadcast, or presence or postgres_changes at any given time.

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.

3 participants