Skip to content

perf: Let HostnameCache worker thread idle out (JAVA-653) - #5817

Open
runningcode wants to merge 2 commits into
mainfrom
no/perf/hostname-cache-idle-thread
Open

perf: Let HostnameCache worker thread idle out (JAVA-653)#5817
runningcode wants to merge 2 commits into
mainfrom
no/perf/hostname-cache-idle-thread

Conversation

@runningcode

@runningcode runningcode commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

📜 Description

HostnameCache's executor stays around for the entire process lifetime (that's how ThreadPoolExecutors work by default) even though the cache only refreshes once every 5 hours. It now uses a ThreadPoolExecutor (core = max = 1) with a 30s keep-alive and allowCoreThreadTimeOut(true), so the worker thread self-terminates when idle and is recreated on the next refresh.

Alternatively, we can also use an existing executor for this but this is the smallest change here. Let me know if you think we should go that route.

💡 Motivation and Context

Part of reducing the number of threads created by the SDK: JAVA-653.

💚 How did you test it?

There are some new unit tests, but otherwise relying on ART/JVM to do their thing correctly.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

@linear-code

linear-code Bot commented Jul 22, 2026

Copy link
Copy Markdown

JAVA-653

@sentry

sentry Bot commented Jul 22, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.51.0 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 318.31 ms 365.39 ms 47.08 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
d15471f 369.38 ms 459.08 ms 89.70 ms
bbc35bb 324.88 ms 425.73 ms 100.85 ms
b193867 319.59 ms 403.09 ms 83.50 ms
62b579c 299.75 ms 364.84 ms 65.09 ms
382d6c1 306.85 ms 368.70 ms 61.85 ms
48277cd 320.38 ms 379.90 ms 59.52 ms
5b1a06b 315.40 ms 353.33 ms 37.94 ms
ee747ae 415.92 ms 470.15 ms 54.23 ms
37ec571 366.04 ms 424.28 ms 58.23 ms
462dea2 277.68 ms 359.83 ms 82.15 ms

App size

Revision Plain With Sentry Diff
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
bbc35bb 1.58 MiB 2.12 MiB 553.01 KiB
b193867 1.58 MiB 2.19 MiB 620.00 KiB
62b579c 0 B 0 B 0 B
382d6c1 1.58 MiB 2.29 MiB 719.85 KiB
48277cd 0 B 0 B 0 B
5b1a06b 0 B 0 B 0 B
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
37ec571 0 B 0 B 0 B
462dea2 0 B 0 B 0 B

Previous results on branch: no/perf/hostname-cache-idle-thread

Startup times

Revision Plain With Sentry Diff
148c76a 313.40 ms 375.26 ms 61.86 ms

App size

Revision Plain With Sentry Diff
148c76a 0 B 0 B 0 B

runningcode and others added 2 commits August 4, 2026 16:48
HostnameCache used Executors.newSingleThreadExecutor, whose worker
thread stays alive for the life of the process even though the cache
refreshes at most once every 5 hours. Use a ThreadPoolExecutor with a
keep-alive and allowCoreThreadTimeOut(true) so the thread terminates
when idle and is recreated on the next refresh. Keeping a dedicated
executor (rather than sharing one) preserves the blocking
future.get(1s) timeout behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@runningcode
runningcode force-pushed the no/perf/hostname-cache-idle-thread branch from b03da86 to 8b8d967 Compare August 4, 2026 14:49
@runningcode
runningcode marked this pull request as ready for review August 4, 2026 15:01
Comment on lines +99 to +102
THREAD_KEEP_ALIVE_SECONDS,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new HostnameCacheThreadFactory());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: If executorService.submit() fails, the updateRunning flag is never reset, which permanently disables future hostname cache updates.
Severity: MEDIUM

Suggested Fix

Ensure the updateRunning flag is reset to false even if task submission fails. This can be achieved by wrapping the executorService.submit() call and its subsequent logic in a try...finally block, where the finally block resets the flag. Alternatively, the handleCacheUpdateFailure method could be modified to reset the flag.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: sentry/src/main/java/io/sentry/HostnameCache.java#L99-L102

Potential issue: In `HostnameCache`, if `executorService.submit()` throws a
`RejectedExecutionException` (which can occur if the SDK is shut down), the
`updateRunning` flag is left permanently in a `true` state. The flag is set to `true`
before the task submission, but the logic to reset it to `false` is inside the submitted
task's `finally` block. When submission fails, this block never executes. The
corresponding `catch` block calls `handleCacheUpdateFailure()`, which also fails to
reset the flag. This permanently prevents the hostname cache from being updated.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can only happen if the SDK is shut down and not a regression from this PR.

@runningcode runningcode added the sanity-check PR needs a lightweight review for obvious issues label Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sanity-check PR needs a lightweight review for obvious issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant