Skip to content

Conversation

@cloudwebrtc
Copy link
Contributor

@cloudwebrtc cloudwebrtc commented Jan 27, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Improved publisher connection stability by optimizing connection state management and recovery mechanisms from disconnection and failure events.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 27, 2026

📝 Walkthrough

Walkthrough

Introduces connection caching for publisher connections in the Engine class. A new ensurePublisherConnected() method wraps the existing _publisherEnsureConnected() to prevent duplicate connection attempts by caching the in-progress Future. The cache is reset when the RTCPeerConnection disconnects.

Changes

Cohort / File(s) Summary
Publisher Connection Caching
lib/src/core/engine.dart
Added _publisherConnectionFuture field to cache connection attempts; introduced ensurePublisherConnected() internal method to manage cached Future with automatic reuse; replaced all _publisherEnsureConnected() calls with new method; added cache reset logic when RTCPeerConnection enters Closed, Failed, or Disconnected states; ensures publisher connection after full restart

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A cache for connections, so clever and spry,
No duplicate handshakes as signals fly,
One Future at a time, we're quick to reconnect,
When bonds fall apart, we reset with respect!
Efficiency hops along the network way 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: implementing debouncing for the ensurePublisherConnected method by caching in-progress connection attempts with _publisherConnectionFuture.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@lib/src/core/engine.dart`:
- Around line 506-510: ensurePublisherConnected currently caches the future in
_publisherConnectionFuture but never clears it if _publisherEnsureConnected()
throws or times out, causing permanent failure; modify ensurePublisherConnected
to assign _publisherConnectionFuture = _publisherEnsureConnected() as now, then
await it inside a try/catch, and in the catch block reset
_publisherConnectionFuture to null before rethrowing the error so subsequent
calls can retry; reference functions/fields: ensurePublisherConnected,
_publisherConnectionFuture, and _publisherEnsureConnected.
- Around line 1148-1150: Cached publisher connection future
_publisherConnectionFuture can remain completed after restartConnection()
causing ensurePublisherConnected() to skip renegotiation; when
disposing/recreating the publisher inside restartConnection() clear/reset
_publisherConnectionFuture (set to null or a fresh completer) so
ensurePublisherConnected() will recreate the connection for the new publisher
instance; update restartConnection() teardown path where the old publisher is
disposed to reset _publisherConnectionFuture before new publisher creation.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db929a3 and 8f1741f.

📒 Files selected for processing (1)
  • lib/src/core/engine.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Build for Flutter Android
  • GitHub Check: Build for Flutter Web WASM
  • GitHub Check: Build for Flutter Linux
  • GitHub Check: Build for Flutter Windows
  • GitHub Check: Build for Flutter macOS
  • GitHub Check: Build for Flutter iOS
  • GitHub Check: Build for Flutter Web
🔇 Additional comments (3)
lib/src/core/engine.dart (3)

168-168: LGTM: cached in-flight publisher connection state.

The field addition is clear and well-scoped for debouncing.


411-423: LGTM: avoid sending before publisher is connected.

Good guard to ensure the publisher transport is ready when subscriber is primary.


643-650: LGTM: cache reset on disconnected/failed/closed states.

This keeps the memoized future aligned with connection lifecycle.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +506 to +510
@internal
Future<void> ensurePublisherConnected() async {
_publisherConnectionFuture ??= _publisherEnsureConnected();
await _publisherConnectionFuture;
}
Copy link

@coderabbitai coderabbitai bot Jan 27, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reset cached future on failure to allow retries.

If _publisherEnsureConnected() times out or throws, _publisherConnectionFuture stays in a failed state and all future calls immediately rethrow. Clear the cache on error so subsequent attempts can retry.

🛠️ Proposed fix
 `@internal`
 Future<void> ensurePublisherConnected() async {
   _publisherConnectionFuture ??= _publisherEnsureConnected();
-  await _publisherConnectionFuture;
+  try {
+    await _publisherConnectionFuture;
+  } catch (_) {
+    _publisherConnectionFuture = null;
+    rethrow;
+  }
 }
🤖 Prompt for AI Agents
In `@lib/src/core/engine.dart` around lines 506 - 510, ensurePublisherConnected
currently caches the future in _publisherConnectionFuture but never clears it if
_publisherEnsureConnected() throws or times out, causing permanent failure;
modify ensurePublisherConnected to assign _publisherConnectionFuture =
_publisherEnsureConnected() as now, then await it inside a try/catch, and in the
catch block reset _publisherConnectionFuture to null before rethrowing the error
so subsequent calls can retry; reference functions/fields:
ensurePublisherConnected, _publisherConnectionFuture, and
_publisherEnsureConnected.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think coderabbitai is right, if _publisherEnsureConnected() can throw, _publisherConnectionFuture() will cache the state and rethrow, can you address it ?

Copy link

Choose a reason for hiding this comment

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

@xianshijing-lk, you're absolutely right! The current implementation will cache the failed future state, preventing any retries. I'll prepare the fix for you.

Task: Fix ensurePublisherConnected to reset cache on failure

  • Wrap the await in a try-catch block
  • Reset _publisherConnectionFuture to null before rethrowing
  • This allows subsequent calls to retry the connection

💡 For code changes across multiple files, use @coderabbitai plan in an issue comment

Comment on lines 1148 to 1150
if (_hasPublished) {
await _publisherEnsureConnected();
await ensurePublisherConnected();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Clear cached future on restart to avoid stale success.

restartConnection() disposes and recreates the publisher. If _publisherConnectionFuture was completed in the prior session, ensurePublisherConnected() may no-op and skip negotiation for the new publisher (especially in subscriber-primary + non-fast-publish). Reset the cache when tearing down the old publisher.

🛠️ Proposed fix
       await publisher?.dispose();
       publisher = null;
+      _publisherConnectionFuture = null;
🤖 Prompt for AI Agents
In `@lib/src/core/engine.dart` around lines 1148 - 1150, Cached publisher
connection future _publisherConnectionFuture can remain completed after
restartConnection() causing ensurePublisherConnected() to skip renegotiation;
when disposing/recreating the publisher inside restartConnection() clear/reset
_publisherConnectionFuture (set to null or a fresh completer) so
ensurePublisherConnected() will recreate the connection for the new publisher
instance; update restartConnection() teardown path where the old publisher is
disposed to reset _publisherConnectionFuture before new publisher creation.

Copy link
Contributor

@xianshijing-lk xianshijing-lk left a comment

Choose a reason for hiding this comment

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

please address the ai bot comments, I found it pretty useful.

Comment on lines +506 to +510
@internal
Future<void> ensurePublisherConnected() async {
_publisherConnectionFuture ??= _publisherEnsureConnected();
await _publisherConnectionFuture;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think coderabbitai is right, if _publisherEnsureConnected() can throw, _publisherConnectionFuture() will cache the state and rethrow, can you address it ?

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