Repository navigation
fix(core): Mark transactions that outlive their deadline as deadline_exceeded (JAVA-642) - #6599
Draft
runningcode wants to merge 5 commits into
Draft
runningcode wants to merge 5 commits into
runningcode wants to merge 5 commits into
Conversation
…JAVA-642) The deadline timer counts on System.nanoTime(), which stops while an Android device is suspended. It ran hours late, and after a process freeze it raced the main thread, so ui.load transactions ended hours after the deadline, or measured TTID, TTFD and the app start to a late frame and finished as ok. SentryTracer now measures the deadline on the monotonic ticker, which counts suspend, and ends the transaction and its open spans at the wall time the deadline was reached. Once it has passed, every way of finishing the transaction takes that outcome. ActivityLifecycleIntegration applies it before handling a late first frame, full display or destroy, and PerformanceAndroidEventProcessor adds no app start measurement when the app start span was cut short. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
📲 Install BuildsAndroid
|
Starting a span after the deadline finished and captured the whole transaction on the thread that started the span, which may hold a lock. Return the no-op span only: the overdue deadline timer ends the transaction at the deadline right after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…line Timings now stay exactly as before: the deadline timer ends spans at now() again, spans started after the deadline are recorded, and the ActivityLifecycleIntegration and PerformanceAndroidEventProcessor changes are reverted. Instead, once the monotonic-ticker deadline has passed, Span.finish gives the transaction and any span that finishes after it the status the deadline timer gives: the transaction's own status, or DEADLINE_EXCEEDED. Late frames after a device sleep then no longer report ok, so span.status:ok filters them out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📜 Description
After an Android device sleeps, or after the process is frozen,
ui.loadtransactions can arrive with TTID, TTFD and app start values that are hours long, most of them with statusok.The deadline timer counts on
System.nanoTime(), which stops while the device is suspended. After Doze, the timer still has time left when the app wakes up; after a freeze, it is overdue and races the main thread. Either way, the first frame can finish the TTID, TTFD and app start spans before the timer runs, and the idle timeout then finishes the transaction asok.This keeps every timestamp, duration and measurement as it is, and changes only the status.
SentryTraceralso measures its deadline with aDeadlineonoptions.getMonotonicTicker(), which counts suspend on Android. Once that deadline has passed, the transaction and any span that finishes after it get the status the deadline timer gives: the transaction's own status, orDEADLINE_EXCEEDEDif it has none. The rule is inSpan.finish, which the transaction's root span and every child go through. That covers TTID, TTFD, the app start, network spans, the idle timeout,finish(...),forceFinish(...)and app code. Nothing changes before the deadline.The point is that
span.status:okthen filters these transactions out. Closed #5755 dropped late transactions instead; this keeps them.Side effect:
AppStartExtension.getExtendedEndTime()ignores an extended app start span with statusDEADLINE_EXCEEDED, so the extended app start vital is suppressed when that span finishes after the deadline.No
.apichanges.💡 Motivation and Context
In one customer's data, 84% of the
ui.loadtransactions over 60s wereokwith this signature, so filtering onspan.status:okdidn't remove them.💚 How did you test it?
Unit tests in
SentryTracerTestandActivityLifecycleIntegrationTestuseTestMonotonicTickerto pass the deadline while the timer hasn't run. Each checks that timestamps and measurements matchmainand that only the status changes. Each fails onmain, except the two that check nothing changes before the deadline. Not tried on a device.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
enableStandaloneAppStartTracing) has no deadline, so a first frame drawn after a sleep still makes it hours long with statusok.SentryTracercan capture a transaction twice when two threads finish it at the same moment, for example the deadline timer andonActivityDestroyed. That race is already onmain.🤖 Generated with Claude Code