Conversation
|
[Medium risk] Adjusts which debug properties attach to replay events. The PR appears safe to merge, with a non-blocking issue that can allow extra debug bundles during overlapping captures. Reviews (1) · Last reviewed commit: "fix(replay): keep the replay debug windo..." |
| private fun releaseReplayDebugPropertiesClaim() { | ||
| synchronized(replayDebugPropertiesLock) { | ||
| outstandingReplayDebugClaimAt = null | ||
| } |
There was a problem hiding this comment.
Older captures clear newer claims
releaseReplayDebugPropertiesClaim() clears the current claim without checking who owns it. If capture A stays in beforeSend for over 30 seconds, capture B can replace its expired claim. If A then returns null, its finally clears B's claim. Capture C can now claim while B is still running, letting B and C queue the full debug bundle within 30 seconds.
Give each claim an owner token and release it only when that token still owns the claim. Add a test for this overlap.
Knowledge Base Used: Event capture and delivery
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/src/main/java/com/posthog/PostHog.kt
Line: 871-874
Comment:
**Older captures clear newer claims**
`releaseReplayDebugPropertiesClaim()` clears the current claim without checking who owns it. If capture A stays in `beforeSend` for over 30 seconds, capture B can replace its expired claim. If A then returns `null`, its `finally` clears B's claim. Capture C can now claim while B is still running, letting B and C queue the full debug bundle within 30 seconds.
Give each claim an owner token and release it only when that token still owns the claim. Add a test for this overlap.
**Knowledge Base Used:** [Event capture and delivery](https://app.greptile.com/posthog-org-19734/-/custom-context/knowledge-base/posthog/posthog-android/-/docs/event-capture-and-delivery.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
posthog-android Compliance ReportDate: 2026-10-02 19:27:25 UTC ✅ All Tests Passed!46/46 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
💡 Motivation and Context
Ports PostHog/posthog-ios#859, which is itself a port of PostHog/posthog-js#5144 plus a few mobile-only decisions. Since #782 every captured event carries the full replay debug bundle, which repeats a lot of properties for diagnostics that only need an occasional sample.
Required on every event (when available):
$recording_status,$sdk_debug_replay_event_trigger_status,$sdk_debug_replay_linked_flag_trigger_statusand$sdk_debug_replay_internal_buffer_length.$sdk_debug_pending_queue_sizestays ungated, and SDK values still overwrite a same-named registered super property.The rest of the bundle (
$sdk_debug_session_start,$sdk_debug_replay_capture_mode,$sdk_debug_replay_flush_hold_reason,$sdk_debug_replay_pending_trigger_conditions) only goes on SDK events, meaning names starting with$other than$feature_flag_calledand$snapshot. Eligibility uses the name beforebeforeSend, and custom events never get it.It's attached at most once per 30s of wall clock:
beforeSendcan't also take it. A claim older than 30s counts as leaked.beforeSend, routed to the replay queue as$snapshot, or failing mid-capture releases the claim instead.close().Removes
$sdk_debug_current_session_durationand$sdk_debug_replay_throttle_delay_ms.Every event goes through
PostHog.capture, so whether an event claimed the bundle is tracked on that call rather than on the event. That survivesbeforeSendrenaming or replacing the event without a marker in the properties or a new field onPostHogEvent.captureStatelessnow delegates to an internal helper that reports whether the event reached the queue. No public API change (make apidiff is empty).Where Android differs from iOS:
beforeSendalready runs twice per stateful capture (once inPostHog.capture, again incaptureStateless). That's pre-existing and not changed here; the window commits after both passes. Worth a follow-up to run it once.capture, so a deduplicated$setnever claims.The published session-replay-debug-properties spec still requires the removed keys and per-event attachment. The spec update is in flight.
💚 How did you test it?
New
PostHogTestcases cover:$feature_flag_calledand custom events carrying only the required keys and not arming the windowbeforeSendreleasing, and an event without the bundle not consuming the window when the interval elapses mid-capture$setnot armingbeforeSendnot double-claiming, and renames in both directionsbeforeSendclose()resetting the windowI updated the tests that asserted the full bundle on custom events or the removed keys, and re-recorded the Android batch event-shape snapshot. 13 of the 14 new tests fail against
main; the one that passes there is the no-internal-state guard, which holds by construction../gradlew :posthog:testand:posthog-android:testDebugUnitTestpass, andmake checkFormatandmake apiare clean.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
DRI: @ioannisj
Autonomy: Human-driven (agent-assisted)