RUM-17613: timeseries [4/5] Flush the batch in background - #3719
Conversation
🎉 All green!🧪 All tests passed 🔄 Datadog retried 1 test - 1 passed on retry 🎯 Code Coverage (details) 🔗 Commit SHA: febc38d | Docs | View more details | Give us feedback! |
40a19e5 to
57ac354
Compare
This stack of pull requests is managed by Graphite. Learn more about stacking. |
8f84420 to
a689c33
Compare
a689c33 to
369a5ee
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 369a5eee5a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Sampling kept running while the app sat in background, and the buffered batch was only written on session stop, so points collected before a backgrounding could stay unsent for the rest of the session. The collector now suspends the sampling chain when the active view leaves the foreground and flushes the buffers at that point, attributing the batch to the last foreground context. The suspension is delayed by 200 ms to match ActivityViewTrackingStrategy.STOP_VIEW_DELAY_MS, so an Activity-to-Activity transition is not mistaken for a backgrounding. Sampling state carries a generation counter so a suspension pending on an older generation cannot stop a chain that has since been resumed. Drops TimeseriesConfiguration.collectInBackground: background suspension is now unconditional, so the flag no longer has a meaning. Ref: RUM-17613
369a5ee to
2f61d4f
Compare
| val isEnterForeground = !oldViewType.isForeground && newViewType.isForeground | ||
| val isLeaveForeground = oldViewType.isForeground && !newViewType.isForeground |
There was a problem hiding this comment.
Maybe it is worth to add a callback to the ProcessLifecycleMonitor? Although this approach probably also works.
There was a problem hiding this comment.
Yes, but as long as we catching the rumContext which is required to build proper timeseries batch event - I prefer to keep the existing logic for now. Plus it allows to catch a specific scenario, when app is not fully in foreground, but starting (APPLICATION_LAUNCH) which could be very important for the timeseries
The pending suspend read lastForegroundRumContext at fire time, so a foreground re-entry landing between stopGeneration() and the flush made it attribute the previous view's batch to the new view. Snapshot the context when the stop is scheduled instead.

What does this PR do?
Fixes timeseries not being sent when the app goes to background with a partially filled batch.
Sampling used to keep running in background (unless
collectInBackgroundwas off) and the buffer was only written on session stop, so points collected before a backgrounding could stay unsent for the rest of the session. Now, when the active view leaves the foreground, the collector suspends the sampling chain and flushes the buffers, attributing the batch to the last foreground context — a background flush has no view of its own to attribute to.The suspension is delayed by 200 ms to match
ActivityViewTrackingStrategy.STOP_VIEW_DELAY_MS: an Activity-to-Activity transition leaves no active view for a moment and must not be mistaken for a backgrounding. If the app returns to the foreground within that window, collection simply continues. Sampling state carries a generation counter so a suspension pending on an older generation cannot stop a chain that has since been resumed.TimeseriesConfiguration.collectInBackgroundis dropped: background suspension is now unconditional, so the flag no longer has a meaning.Review checklist (to be filled by reviewers)
Ref: RUM-17613