Skip to content

Commit f6fbf8a

Browse files
committed
Merge branch 'main' into feat/replay-custom-redact
2 parents 8135d28 + 84c28cd commit f6fbf8a

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
### Fixes
1818

19-
-- Incoming Change
19+
- App lag with frame tracking enabled when span finishes after a long time ([#2311](https://github.com/getsentry/sentry-dart/pull/2311))
2020
- Only start frame tracking if we receive valid display refresh data ([#2307](https://github.com/getsentry/sentry-dart/pull/2307))
2121
- Rounding error used on frames.total and reject frame measurements if frames.total is less than frames.slow or frames.frozen ([#2308](https://github.com/getsentry/sentry-dart/pull/2308))
2222
- iOS replay integration when only `onErrorSampleRate` is specified ([#2306](https://github.com/getsentry/sentry-dart/pull/2306))

flutter/lib/src/span_frame_metrics_collector.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class SpanFrameMetricsCollector implements PerformanceContinuousCollector {
4444
@visibleForTesting
4545
int? displayRefreshRate;
4646

47+
@visibleForTesting
48+
int maxFramesToTrack = 10800;
49+
4750
final _stopwatch = Stopwatch();
4851

4952
SpanFrameMetricsCollector(this.options,
@@ -118,6 +121,13 @@ class SpanFrameMetricsCollector implements PerformanceContinuousCollector {
118121
///
119122
/// This method is called for each frame when frame tracking is active.
120123
Future<void> measureFrameDuration(Duration duration) async {
124+
if (frames.length >= maxFramesToTrack) {
125+
options.logger(SentryLevel.warning,
126+
'Frame tracking limit reached. Clearing frames and cancelling frame tracking for all active spans');
127+
clear();
128+
return;
129+
}
130+
121131
// Using the stopwatch to measure the frame duration is flaky in ci
122132
if (_isTestMode) {
123133
// ignore: invalid_use_of_internal_member
@@ -267,6 +277,7 @@ class SpanFrameMetricsCollector implements PerformanceContinuousCollector {
267277
@override
268278
void clear() {
269279
_isTrackingPaused = true;
280+
_stopwatch.reset();
270281
frames.clear();
271282
activeSpans.clear();
272283
displayRefreshRate = null;

flutter/test/span_frame_metrics_collector_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,33 @@ void main() {
261261

262262
expect(sut.isTrackingPaused, isTrue);
263263
});
264+
265+
test(
266+
'measureFrameDuration stops and removes all frames when reaching frame limit',
267+
() async {
268+
final sut = fixture.sut;
269+
final span = MockSentrySpan();
270+
271+
when(span.startTimestamp).thenReturn(DateTime.now());
272+
sut.activeSpans.add(span);
273+
sut.frames[DateTime.now()] = 1;
274+
const maxFramesToTrack = 1000;
275+
sut.maxFramesToTrack = maxFramesToTrack;
276+
277+
for (var i = 1; i <= maxFramesToTrack; i++) {
278+
await Future<void>.delayed(
279+
Duration(milliseconds: 1)); // Add a small delay
280+
if (i == maxFramesToTrack - 1) {
281+
expect(sut.frames.length, maxFramesToTrack - 1);
282+
}
283+
await sut.measureFrameDuration(Duration.zero);
284+
}
285+
286+
expect(sut.frames, isEmpty);
287+
expect(sut.activeSpans, isEmpty);
288+
expect(sut.displayRefreshRate, isNull);
289+
expect(sut.isTrackingPaused, isTrue);
290+
});
264291
}
265292

266293
class Fixture {

0 commit comments

Comments
 (0)