Skip to content

Conversation

@Brazol
Copy link
Contributor

@Brazol Brazol commented Dec 3, 2025

Summary by CodeRabbit

  • New Features

    • Exported media device serialization and new connection-quality event payloads.
  • Bug Fixes

    • Stats reporter now skips processing when unmounted to avoid spurious work.
  • Improvements

    • Enhanced SFU statistics with additional trace data and broader trace collection.
    • Improved reconnection diagnostics and lifecycle guards for more reliable behavior.
    • Standardized JSON keys and enum/value formats across public payloads.

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

@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Walkthrough

Introduces zoned and base tracing across Call and Session paths (CallSession.getTrace() now returns multiple TraceSlice), appends media-device traces to SFU stats, renames trace/event keys to camelCase, updates many SFU toJson() serializations to camelCase/value enums, adds lifecycle guards, and exposes RtcMediaDevice.toJson().

Changes

Cohort / File(s) Summary
Changelog
packages/stream_video/CHANGELOG.md
Added "Unreleased" entry noting improved SFU stats implementation.
Call core & reconnection traces
packages/stream_video/lib/src/call/call.dart
Flatten leftover trace extraction from previous session and rename reconnect trace keys to camelCase; use local strategy.name for trace payloads.
Call session lifecycle & tracing
packages/stream_video/lib/src/call/session/call_session.dart
Added zoned tracer, changed getTrace() to return List<TraceSlice>, added _isLeavingOrClosed guard, updated timeout tracing/handling and used zoned tracer for zone-run operations.
Session factory trace IDs
packages/stream_video/lib/src/call/session/call_session_factory.dart
Include sfuName in tracer name and trace IDs; removed an extra 'create' trace call.
SFU stats assembly
packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart
Collects RtcMediaDeviceNotifier.instance.getTrace() and appends it to SFU stats traces (expanded list).
Stats processing guards
packages/stream_video/lib/src/call/stats/stats_reporter.dart
Short-circuit run() and _processStats() when not mounted.
SFU JSON shape & enum serialization
packages/stream_video/lib/src/sfu/sfu_extensions.dart
Large-scale toJson() updates: snake_case → camelCase keys, enums serialized via .value, conditional field emission, removed some SDP parsing, and added connection-quality JSON extensions.
WebRTC debug logs
packages/stream_video/lib/src/webrtc/rtc_manager.dart
Added debug logging to setTrackFacingMode and setCameraVideoParameters.
Media device model & notifier tracing
packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device.dart, packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart
Added public RtcMediaDevice.toJson() and tracing instrumentation + getTrace() on RtcMediaDeviceNotifier (enumerateDevices, pause/resume audio, regain audio focus).
Tests updated for trace shape
packages/stream_video/test/src/call/fixtures/call_test_helpers.dart
Mocks updated to return List<TraceSlice> from callSession.getTrace() to match new signature/shape.

Sequence Diagram(s)

sequenceDiagram
    participant Call as Call / CallSession
    participant Tracer as Tracers (_tracer, _zonedTracer)
    participant Zone as TracerZone
    participant Stats as SfuStatsReporter
    participant Media as RtcMediaDeviceNotifier
    participant SFU as SFU/Backend

    Call->>Tracer: getTrace() -> List<TraceSlice> ([_tracer.take(), _zonedTracer.take()])
    Zone->>Call: run zoned ops (setCamera/setMicrophone) using _zonedTracer
    Call->>Tracer: zoned tracer logs events

    Stats->>Call: request session traces
    Call-->>Stats: returns expanded traces
    Stats->>Media: getTrace()
    Media-->>Stats: media-device TraceSlice
    Stats->>Stats: assemble traces (...sessionTrace, mediaDeviceTrace)
    Stats->>SFU: send SFU stats payload (includes traces)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing attention:
    • packages/.../sfu/sfu_extensions.dart (widespread public JSON shape changes).
    • All call sites and tests that consume CallSession.getTrace() (signature/shape change).
    • Trace ID/name and sfuName propagation in call_session_factory.dart.
    • SFU stats assembly handling of mixed/expanded trace lists and the added media-device trace.

Possibly related PRs

Suggested reviewers

  • renefloor
  • xsahil03x

Poem

🐇 I hop through traces, slice by slice,

keys now camel, logs concise,
Devices whisper into the stream,
Stats tuck them in—a tidy dream,
Rabbit winks and pats the code with glee.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided. The PR lacks required sections including Goal, Implementation details, Testing approach, and Contributor checklist as specified in the template. Add a comprehensive description following the template: include the Goal (why this improves SFU stats), Implementation details (tracing, stats collection changes), Testing approach, and complete the Contributor checklist.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore(llc): improved sfu stats' accurately describes the main change—improvements to SFU stats implementation across multiple files in the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/improve-sfu-stats

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov
Copy link

codecov bot commented Dec 3, 2025

Codecov Report

❌ Patch coverage is 5.19481% with 146 lines in your changes missing coverage. Please review.
✅ Project coverage is 6.29%. Comparing base (8bba862) to head (bdcbe8f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...kages/stream_video/lib/src/sfu/sfu_extensions.dart 0.00% 104 Missing ⚠️
...tream_video/lib/src/call/session/call_session.dart 0.00% 15 Missing ⚠️
...tc/rtc_media_device/rtc_media_device_notifier.dart 0.00% 7 Missing ⚠️
.../src/webrtc/rtc_media_device/rtc_media_device.dart 0.00% 6 Missing ⚠️
...m_video/lib/src/call/stats/sfu_stats_reporter.dart 0.00% 4 Missing ⚠️
...kages/stream_video/lib/src/webrtc/rtc_manager.dart 0.00% 4 Missing ⚠️
packages/stream_video/lib/src/call/call.dart 80.00% 2 Missing ⚠️
...deo/lib/src/call/session/call_session_factory.dart 0.00% 2 Missing ⚠️
...tream_video/lib/src/call/stats/stats_reporter.dart 0.00% 2 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main   #1122   +/-   ##
=====================================
  Coverage   6.29%   6.29%           
=====================================
  Files        593     593           
  Lines      40849   40887   +38     
=====================================
+ Hits        2570    2574    +4     
- Misses     38279   38313   +34     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Brazol Brazol marked this pull request as ready for review December 4, 2025 12:04
@Brazol Brazol requested a review from a team as a code owner December 4, 2025 12:04
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: 5

🧹 Nitpick comments (2)
packages/stream_video/lib/src/call/call.dart (1)

1489-1552: Verify trace payload for strategy and downstream expectations

The reconnect traces now emit:

  • 'callReconnect', 'callReconnectSuccess', 'callReconnectFailed' (camelCase)
  • payload { 'strategy': strategy, ... } where strategy is SfuReconnectionStrategy.

If TraceRecord → JSON serialization does not special-case this enum/Protobuf type, jsonEncode of SFU stats may fail. Also, changing event names is a telemetry contract change.

Consider reverting payload to a plain string if needed:

-        _session?.trace('callReconnect', {
-          'strategy': strategy,
-        });
+        _session?.trace('callReconnect', {
+          'strategy': strategy.name,
+        });
...
-          _session?.trace('callReconnectSuccess', {
-            'strategy': strategy,
-          });
+          _session?.trace('callReconnectSuccess', {
+            'strategy': strategy.name,
+          });
...
-              _session?.trace('callReconnectFailed', {
-                'strategy': strategy,
-                'error': error.toString(),
-              });
+              _session?.trace('callReconnectFailed', {
+                'strategy': strategy.name,
+                'error': error.toString(),
+              });

And please double‑check that backend consumers are ready for the new camelCase event names before deploying.

packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (1)

2-3: RtcMediaDeviceNotifier tracing is well-scoped and non-intrusive

  • _tracer + getTrace() provide a clean hook for SFU stats to pull device‑level traces.
  • enumerateDevices() logs a JSON‑friendly view of devices.
  • pauseAudioPlayout, resumeAudioPlayout, and regainAndroidAudioFocus emit concise trace events without altering behavior.

This is a good level of observability for debugging audio/device issues.

If you later need to reduce noise, you could gate _tracer.trace(...) behind a simple “device tracing enabled” flag, similar to the SFU stats flag.

Also applies to: 7-8, 45-50, 155-158, 197-216

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 807e750 and c0e6ab1.

📒 Files selected for processing (11)
  • packages/stream_video/CHANGELOG.md (1 hunks)
  • packages/stream_video/lib/src/call/call.dart (4 hunks)
  • packages/stream_video/lib/src/call/session/call_session.dart (11 hunks)
  • packages/stream_video/lib/src/call/session/call_session_factory.dart (1 hunks)
  • packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart (1 hunks)
  • packages/stream_video/lib/src/call/stats/stats_reporter.dart (2 hunks)
  • packages/stream_video/lib/src/sfu/sfu_extensions.dart (19 hunks)
  • packages/stream_video/lib/src/webrtc/rtc_manager.dart (2 hunks)
  • packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device.dart (1 hunks)
  • packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (5 hunks)
  • packages/stream_video/test/src/call/fixtures/call_test_helpers.dart (1 hunks)
⏰ 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). (2)
  • GitHub Check: build
  • GitHub Check: analyze
🔇 Additional comments (26)
packages/stream_video/lib/src/sfu/sfu_extensions.dart (11)

14-31: LGTM!

New imports and camelCase key naming in CodecX.toJson() are consistent with the PR objectives for standardizing JSON serialization.


85-98: LGTM!

camelCase keys and proper enum .value access for quality are consistent with the standardization effort.


110-119: LGTM!

Conditional field emission using has*() checks is a clean approach that avoids emitting unset protobuf fields.


121-130: LGTM!

Proper enum .value access for SDK type.


160-187: LGTM!

Consistent camelCase keys and enum .value access across these request extensions.


376-385: LGTM!

The reconnectStrategy.toDto().value pattern is appropriate when the domain model needs conversion to a DTO before accessing the protobuf value.


406-414: Verify intentional use of .index for connectionQuality.

connectionQuality.index returns the enum's ordinal position (0, 1, 2...) rather than its semantic value. Other enums in this file use .value which typically returns the protobuf field value. Confirm this is the intended serialization format.


387-393: Same concern as goAwayReason: potential .toString() vs .value inconsistency.

Verify whether callEndedReason should use .value for consistency with other enums.


416-458: LGTM!

Both track event extensions follow consistent patterns with toDTO().value for trackType and properly structured nested participant objects.


484-504: LGTM!

SDP fields are properly emitted directly, and the camelCase key naming is consistent throughout the join request serialization.


360-366: Remove this comment — the code is correct.

SfuGoAwayReason is a plain Dart enum without a .value property. The custom toString() override returns the enum name directly, which is the correct serialization approach for this enum type. The file's mixed use of .value and .toString() reflects different enum sources: protobuf-generated enums use .value, while plain Dart enums use .toString().

packages/stream_video/CHANGELOG.md (1)

1-4: Changelog entry matches implementation scope

The “Improved SFU stats implementation.” note is accurate and scoped correctly to the telemetry/tracing changes in this PR.

packages/stream_video/lib/src/call/stats/stats_reporter.dart (1)

46-55: Mounted guards in stats pipeline look correct

Early returns on !mounted in run() and _processStats() cleanly avoid post‑dispose work while still yielding the latest stats snapshot.

Also applies to: 97-99

packages/stream_video/test/src/call/fixtures/call_test_helpers.dart (1)

303-312: Mocked getTrace correctly updated to List<TraceSlice>

The mock now matches the new CallSession.getTrace() contract by returning a single empty TraceSlice in a list, which is sufficient for exercising callers that flatten snapshots.

packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device.dart (1)

47-54: RtcMediaDevice.toJson is minimal and sufficient for telemetry

The JSON shape (id, label, groupId, kind as alias) is consistent and safe to feed into tracing/SFU stats.

packages/stream_video/lib/src/call/session/call_session_factory.dart (1)

75-85: Tracer naming and leftover record IDs look consistent

Including sessionSeq and sfuName in both tracer name and leftover record IDs will make multi‑SFU/session traces easier to correlate without changing runtime behavior.

packages/stream_video/lib/src/call/stats/sfu_stats_reporter.dart (1)

186-199: Media-device notifier trace integration into SFU stats looks correct

Aggregating:

  • subscriber/publisher tracer slices
  • all callSession.getTrace() slices (...sessionTrace)
  • the RtcMediaDeviceNotifier trace slice

into a single traces list, then expanding snapshots and rolling back on failure, fits the existing trace model without changing semantics.

packages/stream_video/lib/src/call/session/call_session.dart (9)

48-48: Good addition of lifecycle guard.

The _isLeavingOrClosed flag helps prevent operations during shutdown states, which is a solid defensive programming practice.


108-108: LGTM - dual tracing facility added.

The addition of _zonedTracer supports the PR's goal of introducing dual tracing mechanisms for better SFU stats instrumentation.


141-144: LGTM - both tracers controlled consistently.

Correctly enables/disables both tracing facilities together.


595-632: LGTM - consistent lifecycle state management.

The _isLeavingOrClosed flag is properly set in all shutdown paths (leave, close, and dispose), ensuring consistent state tracking during session teardown.


697-699: LGTM - enhanced observability.

Adding explicit tracing for connection quality changes improves debugging and monitoring capabilities.


920-924: LGTM - appropriate guard against renegotiation during shutdown.

The guard correctly prevents renegotiation when the session is leaving/closed or disconnected. Note that the log message "call is disconnected" doesn't fully reflect the _isLeavingOrClosed case, but this is a minor clarity issue.


1043-1064: LGTM - enhanced tracing for camera operations.

Wrapping camera enable/disable in a TracerZone provides better instrumentation for debugging media device issues, aligning with the PR's goal of improved SFU stats.


1066-1087: LGTM - consistent tracing for microphone operations.

Microphone operations now have the same detailed tracing as camera operations, providing comprehensive media device instrumentation.


137-139: All callers of CallSession.getTrace() have been properly updated to handle the new List<TraceSlice> return type:

  • sfu_stats_reporter.dart uses the spread operator (...sessionTrace) to add items to the traces list
  • call.dart correctly processes the list with .expand((slice) => slice.snapshot).toList()
  • Test fixtures in call_test_helpers.dart have been updated to mock the list return type

No breaking usages remain in the codebase.

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stream_video/lib/src/call/session/call_session.dart (1)

619-622: Missing _zonedTracer.dispose() call.

The base _tracer is disposed at line 621, but _zonedTracer is not disposed. This could lead to a resource leak if Tracer.dispose() releases resources.

Apply this diff:

     statsReporter?.dispose();
     statsReporter = null;
 
     await rtcManager?.dispose();
     rtcManager = null;
     _tracer.dispose();
+    _zonedTracer.dispose();
     _peerConnectionCheckTimer?.cancel();
♻️ Duplicate comments (1)
packages/stream_video/lib/src/call/session/call_session.dart (1)

465-470: Past issue resolved and timeout tracing added.

The duration formatting fix (joinResponseTimeout.inMilliseconds) correctly addresses the previous review comment. The added joinRequestTimeout trace improves visibility into connection failures.

🧹 Nitpick comments (3)
packages/stream_video/lib/src/sfu/sfu_extensions.dart (3)

395-404: Rename loop variable in connectionQualityUpdates map for clarity.

Here the lambda uses codec as the variable name, but the list is connectionQualityUpdates, which likely contains SfuConnectionQualityInfo items, not codecs. Renaming improves readability and reduces confusion:

-      'connectionQualityUpdates': connectionQualityUpdates
-          .map((codec) => codec.toJson())
-          .toList(),
+      'connectionQualityUpdates': connectionQualityUpdates
+          .map((update) => update.toJson())
+          .toList(),

360-366: Align remaining enum toString() usages with the new value‑based convention (if desired).

Most SFU enums are now serialized via .value (or toDto().value), but these still use .toString():

  • Line 363: goAwayReason.toString()
  • Line 380: code.toString()
  • Line 390: callEndedReason.toString()
  • Lines 500–502: source.toString() and capabilities.map((c) => c.toString())

If the goal is a consistent, stable JSON schema (and to avoid including Dart enum type prefixes in the payload), you may want to switch these to the same value representation you use elsewhere (or introduce a dedicated DTO/value mapping). If they are intentionally using full toString() for backwards compatibility, consider adding a short comment to document that.

Also applies to: 376-385, 387-392, 484-503


416-458: Consider normalizing publishedTracks serialization away from toString().

Inside the participant payload for SfuTrackPublishedEventJsonX / SfuTrackUnpublishedEventJsonX:

'publishedTracks': participant.publishedTracks
    .map((track) => track.toString())
    .toList(),

Other track‑type fields in this file use .value or toDTO().value. If publishedTracks contains the same enum type (or something similar), using .toString() may produce verbose implementation‑specific strings instead of the stable values the rest of the API emits.

If there’s a corresponding .value/DTO or other stable identifier for these track entries, consider switching to that for consistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c0e6ab1 and 1fdb530.

📒 Files selected for processing (3)
  • packages/stream_video/lib/src/call/session/call_session.dart (11 hunks)
  • packages/stream_video/lib/src/sfu/sfu_extensions.dart (19 hunks)
  • packages/stream_video/lib/src/webrtc/rtc_manager.dart (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_video/lib/src/webrtc/rtc_manager.dart
🧰 Additional context used
🪛 GitHub Actions: legacy_version_analyze
packages/stream_video/lib/src/sfu/sfu_extensions.dart

[warning] 14-14: Unused import: '../utils/extensions.dart'. Try removing the import directive.

⏰ 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
  • GitHub Check: analyze
  • GitHub Check: stream_video_push_notification
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video_flutter
  • GitHub Check: stream_video
  • GitHub Check: iOS Build (Dogfooding)
🔇 Additional comments (6)
packages/stream_video/lib/src/call/session/call_session.dart (5)

107-107: LGTM on the new tracing and lifecycle fields.

The dual tracer pattern (_tracer for base events, _zonedTracer for zoned UI operations) and the _isLeavingOrClosed lifecycle guard are well-designed additions that improve tracing granularity and prevent race conditions during shutdown.

Also applies to: 125-125


137-144: LGTM on trace management updates.

The getTrace() now correctly aggregates traces from both tracers, and setTraceEnabled properly synchronizes the enabled state across both.


697-699: LGTM on ConnectionQualityChanged trace.

Adding this trace maintains consistency with other SFU event tracing and improves visibility into connection quality changes.


920-924: LGTM on the renegotiation guard enhancement.

Checking _isLeavingOrClosed first provides a fast path to prevent renegotiation attempts during session teardown, avoiding potential race conditions with the async shutdown sequence.


1052-1061: LGTM on zoned tracer integration for media device operations.

Using _zonedTracer for setCameraEnabled and setMicrophoneEnabled appropriately separates user-initiated media device traces from base SFU event traces, aligning with the dual-tracing architecture introduced in this PR.

Also applies to: 1075-1084

packages/stream_video/lib/src/sfu/sfu_extensions.dart (1)

406-413: Double‑check connectionQuality serialization via enum index.

connectionQuality is exported as connectionQuality.index, which ties the wire format to the enum’s declaration order. If the backend or analytics expect a named value (string) or a specific numeric mapping, this could be fragile.

Confirm that index is the agreed wire representation; if not, consider a stable value (e.g., .value or an explicit mapping).

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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stream_video/lib/src/sfu/sfu_extensions.dart (1)

359-392: Use .value for protobuf enums goAwayReason and callEndedReason.

GoAwayReason and CallEndedReason extend $pb.ProtobufEnum and should use .value for consistency with other protobuf enums throughout this file (e.g., trackType.value, peerType.value). Note: code is a Dart enum (SfuErrorCode), so .toString() is appropriate and should not be changed.

 extension SfuGoAwayEventJsonX on SfuGoAwayEvent {
   Map<String, dynamic> toJson() {
     return {
-      'goAwayReason': goAwayReason.toString(),
+      'goAwayReason': goAwayReason.value,
     };
   }
 }
 extension SfuCallEndedEventJsonX on SfuCallEndedEvent {
   Map<String, dynamic> toJson() {
     return {
-      'callEndedReason': callEndedReason.toString(),
+      'callEndedReason': callEndedReason.value,
     };
   }
 }
♻️ Duplicate comments (1)
packages/stream_video/lib/src/call/call.dart (1)

969-975: Fix null-safety on _previousSession when flattening trace slices

_previousSession?.getTrace().expand(...) is not null-safe: the result of _previousSession?.getTrace() is nullable, so calling .expand on it fails static analysis and would throw if _previousSession is null. This matches the earlier review concern and will break first join/reconnect flows where _previousSession is legitimately null.

Apply this diff to make the access null-safe and keep types aligned:

-        leftoverTraceRecords:
-            _previousSession
-                ?.getTrace()
-                .expand((slice) => slice.snapshot)
-                .toList() ??
-            const [],
+        leftoverTraceRecords:
+            _previousSession == null
+                ? const []
+                : _previousSession!
+                    .getTrace()
+                    .expand((slice) => slice.snapshot)
+                    .toList(),
🧹 Nitpick comments (1)
packages/stream_video/lib/src/call/call.dart (1)

1489-1491: Consider logging the effective reconnect strategy instead of the initial one

The new traces use the method argument strategy.name:

  • callReconnect
  • callReconnectSuccess
  • callReconnectFailed

However, _reconnectStrategy can change inside the loop (e.g. from fast to rejoin after several failed attempts). If you want traces to reflect the actual strategy used for that attempt, consider switching these to _reconnectStrategy.name.

For example:

-        _session?.trace('callReconnect', {
-          'strategy': strategy.name,
-        });
+        _session?.trace('callReconnect', {
+          'strategy': _reconnectStrategy.name,
+        });
...
-          _session?.trace('callReconnectSuccess', {
-            'strategy': strategy.name,
-          });
+          _session?.trace('callReconnectSuccess', {
+            'strategy': _reconnectStrategy.name,
+          });
...
-              _session?.trace('callReconnectFailed', {
-                'strategy': strategy.name,
+              _session?.trace('callReconnectFailed', {
+                'strategy': _reconnectStrategy.name,

Also applies to: 1539-1541, 1549-1552

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1fdb530 and af96abe.

📒 Files selected for processing (3)
  • packages/stream_video/CHANGELOG.md (1 hunks)
  • packages/stream_video/lib/src/call/call.dart (4 hunks)
  • packages/stream_video/lib/src/sfu/sfu_extensions.dart (19 hunks)
⏰ 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). (6)
  • GitHub Check: analyze
  • GitHub Check: build
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video_push_notification
  • GitHub Check: stream_video
  • GitHub Check: stream_video_flutter
🔇 Additional comments (8)
packages/stream_video/CHANGELOG.md (1)

7-7: LGTM!

The changelog entry accurately reflects the PR's improvements to SFU stats. The placement under "🐞 Fixed" is consistent with the codebase's style for enhancements, and the wording is appropriately concise for a user-facing changelog.

packages/stream_video/lib/src/sfu/sfu_extensions.dart (7)

17-31: LGTM!

New imports support the added extensions, and CodecX.toJson() correctly uses camelCase keys.


67-97: LGTM!

The previous inconsistency with trackType.toString() has been addressed. Both trackType.value and quality.value now follow the consistent .value pattern for enum serialization.


109-129: LGTM!

Good use of hasSdk(), hasOs(), etc., guards for conditional field emission in ClientDetailsX, and consistent .value enum serialization throughout.


188-265: LGTM!

Consistent camelCase key naming and .value enum serialization across UpdateMuteStatesRequestX, TrackMuteStateX, UpdateSubscriptionsRequestX, TrackSubscriptionDetailsX, and ReconnectDetailsX.


287-348: LGTM!

The trackType.toDTO().value pattern correctly converts domain model enums to DTOs before accessing .value, maintaining consistency with protobuf serialization.


415-457: LGTM!

Both SfuTrackPublishedEventJsonX and SfuTrackUnpublishedEventJsonX follow consistent patterns with camelCase keys and trackType.toDTO().value for enum serialization.


459-504: LGTM with minor note on source.toString() and capabilities serialization.

PublishOptionX, SubscribeOptionX, and JoinRequestX correctly use .value for trackType. The source.toString() and capabilities.map((c) => c.toString()) at lines 499 and 501 follow the same pattern as other non-protobuf enums flagged earlier.

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: 0

🧹 Nitpick comments (1)
packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (1)

198-198: Consider tracing after operation completion for consistency.

The pauseAudioPlayout(), resumeAudioPlayout(), and regainAndroidAudioFocus() methods trace before the asynchronous operations complete. This differs from enumerateDevices() which traces after success.

While tracing invocations is useful, consider whether you want to:

  • Trace after the Future completes (to confirm success)
  • Trace on both invocation and completion
  • Keep the current pattern if invocation tracking is sufficient

The current approach means traces will be recorded even if the underlying operations fail.

Also applies to: 205-205, 215-215

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between af96abe and bdcbe8f.

📒 Files selected for processing (1)
  • packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (5 hunks)
⏰ 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). (8)
  • GitHub Check: analyze_legacy_version
  • GitHub Check: iOS Build (Dogfooding)
  • GitHub Check: stream_video_push_notification
  • GitHub Check: stream_video_flutter
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video
  • GitHub Check: analyze
  • GitHub Check: build
🔇 Additional comments (3)
packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (3)

2-3: LGTM!

The import additions support the new tracing infrastructure. The meta package provides the @internal annotation, and the tracer import enables tracing functionality.

Also applies to: 8-8


156-159: RtcMediaDevice.toJson() is properly implemented.

The toJson() method exists on RtcMediaDevice (line 47 of rtc_media_device.dart) and returns Map<String, dynamic>. The tracing code correctly serializes devices using this method.


46-51: Tracer initialization with Tracer(null) is valid and intentional.

The Tracer constructor accepts a nullable String parameter (Tracer(this.id) where id is String?). Using Tracer(null) is the correct pattern for singleton components like RtcMediaDeviceNotifier that aren't tied to specific call sessions. This same pattern is already used elsewhere in the codebase (e.g., CallSession._zonedTracer).

@Brazol Brazol merged commit fffad2b into main Dec 4, 2025
15 of 16 checks passed
@Brazol Brazol deleted the chore/improve-sfu-stats branch December 4, 2025 14:03
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