getsentry / getsentry/sentry-java
Missing replay screenshots cause segments to not include latest data
- Dominant language
- Kotlin
- Stars
- 1.4k
- Forks
- 478
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 67
Description
### Description
Consider the following code that creates segments in response to a screenshot being captured
https://github.com/getsentry/sentry-java/blob/f6e97b16af433985fe3ace28ffa383740322fe9f/sentry-android-replay/src/main/java/io/sentry/android/replay/capture/SessionCaptureStrategy.kt#L75-L124
Specifically,
https://github.com/getsentry/sentry-java/blob/f6e97b16af433985fe3ace28ffa383740322fe9f/sentry-android-replay/src/main/java/io/sentry/android/replay/capture/SessionCaptureStrategy.kt#L103-L105
If there is a gap between frames of more than `sessionSegmentDuration`, a segment would be created only for the duration prior to this frame.
I've noticed this while investigating why breadcrumbs are sometimes not send on Flutter - it's because if there are no changes on the UI, there is no frame created but when next there are some changes (and breadcrumbs created for UI taps), these **were not sent because**:
- the current segment start timestamp was the end timestamp of the previous segment
- the duration of the segment was capped at the `sessionSegmentDuration` (5 seconds at the moment)
thus when the current screenshot timestamp was, for example, a minute after the previous one (because the app sat idle), it would take additional 60/5 = 12 frames (12 seconds when the user actively did something on the UI) to catch up; or actually 12 + at least additional 3 for those 12 seconds
I've tried a minor change of passing the actual duration between the last segment end-timestamp and the current frame timestamp, although I'm not sure that is the way to go:
```kotlin
val now = dateProvider.currentTimeMillis
val duration = now - currentSegmentTimestamp.time
if ((duration >= options.experimental.sessionReplay.sessionSegmentDuration)) {
val segment =
createSegmentInternal(
duration,
currentSegmentTimestamp,
```
Instead, I think it may be necessary to either loop here or add more job instances: `replayExecutor.submitSafely(options, "$TAG.add_frame") {`
Contributor guide
Assessment
This issue has not been assessed yet.