perf(core): Reuse shared executor for transaction timeouts (SDK-1347)#5646
Draft
runningcode wants to merge 2 commits into
Draft
perf(core): Reuse shared executor for transaction timeouts (SDK-1347)#5646runningcode wants to merge 2 commits into
runningcode wants to merge 2 commits into
Conversation
SentryTracer created a dedicated java.util.Timer (a new thread) per transaction that had an idle or deadline timeout. For apps with many transactions (screen loads, HTTP spans) this churned threads and added CPU overhead. Schedule the idle/deadline timeouts on the SDK's shared SentryExecutorService (a single ScheduledThreadPoolExecutor) instead, so no per-transaction thread is created. The executor is set with removeOnCancelPolicy(true) so timeouts that are cancelled early (the common case) are evicted from the queue immediately rather than lingering. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📲 Install BuildsAndroid
|
Contributor
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 18c0bc2 | 306.73 ms | 349.77 ms | 43.03 ms |
| 0eaac1e | 316.82 ms | 357.34 ms | 40.52 ms |
| d15471f | 303.49 ms | 439.08 ms | 135.59 ms |
| fc5ccaf | 276.52 ms | 370.46 ms | 93.93 ms |
| e2dce0b | 308.96 ms | 360.10 ms | 51.14 ms |
| 5b1a06b | 352.27 ms | 413.70 ms | 61.43 ms |
| 37ec571 | 366.04 ms | 424.28 ms | 58.23 ms |
| 9fbb112 | 361.43 ms | 427.57 ms | 66.14 ms |
| bbc35bb | 324.88 ms | 425.73 ms | 100.85 ms |
| ff8eea4 | 313.42 ms | 337.08 ms | 23.66 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 18c0bc2 | 1.58 MiB | 2.13 MiB | 557.33 KiB |
| 0eaac1e | 1.58 MiB | 2.19 MiB | 619.17 KiB |
| d15471f | 1.58 MiB | 2.13 MiB | 559.54 KiB |
| fc5ccaf | 1.58 MiB | 2.13 MiB | 557.54 KiB |
| e2dce0b | 0 B | 0 B | 0 B |
| 5b1a06b | 0 B | 0 B | 0 B |
| 37ec571 | 0 B | 0 B | 0 B |
| 9fbb112 | 1.58 MiB | 2.11 MiB | 539.18 KiB |
| bbc35bb | 1.58 MiB | 2.12 MiB | 553.01 KiB |
| ff8eea4 | 1.58 MiB | 2.28 MiB | 718.64 KiB |
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
SentryTracercreated a dedicatedjava.util.Timer— i.e. a new thread — for every transaction that had an idle or deadline timeout. This change schedules those timeouts on the SDK's existing sharedSentryExecutorService(a singleScheduledThreadPoolExecutor) instead, so no per-transaction thread is created.TimerTasks becomeFuture<?>s scheduled viaISentryExecutorService.schedule(...).setRemoveOnCancelPolicy(true)so timeouts that are cancelled early (the common case — a transaction finishing before its idle/deadline) are evicted from the work queue immediately instead of lingering until their scheduled time.💡 Motivation and Context
Part of the Reduce SDK init time [Android] effort — specifically SDK-1347 (reduce the number of threads the SDK creates) and the thread/executor audit in JAVA-570. A per-transaction
Timerthread is the SDK's largest source of thread churn at runtime; apps with many auto-instrumented transactions (activity/navigation/HTTP) paid a thread create+teardown each time. The sharedScheduledThreadPoolExecutoris alive for the whole transaction lifetime, so it is a safe host for these timeouts.In production the shared executor is activated during
Sentry.init, before any transaction is created. Tests that previously relied on the always-on per-transactionTimernow provide a real executor (or disable the transaction timeouts when isolating an unrelated scheduled task).💚 How did you test it?
SentryTracerTestupdated to assert the new future/scheduler state (incl. reschedule-on-child-finish and the closed-executor fallback); full:sentry:test,:sentry-android-core:testDebugUnitTest, and:sentry-android-navigation:testDebugUnitTestare green.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
Further thread consolidation candidates from the JAVA-570 audit:
DefaultAndroidEventProcessor's throwaway init-path executor, and folding the remainingnew Timer(true)sites (DefaultCompositePerformanceCollector,RateLimiter,LifecycleWatcher) onto the shared scheduler.SDK-1347
JAVA-570