Offload fallback DNS from event loops#2272
Closed
pavel-ptashyts wants to merge 5 commits into
Closed
Conversation
The legacy per-request NameResolver path still executes the JDK DefaultNameResolver on the caller thread. Redirects and SOCKS proxy bootstrap can enter that path from a Netty event-loop thread, so a cold or slow OS lookup can park the loop. Add an internal resolver executor and use it only when the fallback NameResolver path is invoked from an AHC event loop. AddressResolverGroup users stay on the existing async path, off-loop initial execute calls keep their current behavior, and resolver results are completed back on the original event loop before the request flow continues. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex <codex@openai.com>
The fallback resolver pool was always enabled, matched the I/O thread count, and used an unbounded queue. It also discarded queued resolutions during client shutdown, which could leave their promises incomplete. Expose enable, thread-count, and queue-size settings. Bound the queue, fail tracked work on shutdown, and reject overflow deterministically. Limit automatic offload to AHC's default blocking resolver so custom resolvers keep their existing caller-thread contract. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex <codex@openai.com>
Mark the new fallback resolver offload configuration methods as introduced in 3.0.12 and clarify that the queue-size setting controls queued work rather than active workers. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex <codex@openai.com>
Keep fallback resolver offloading opt-in so existing clients preserve inline resolution unless they explicitly enable the worker pool. Cover both the disabled default and enabled behavior without leaking cached test configuration into later tests. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex <codex@openai.com>
pavel-ptashyts
force-pushed
the
perf/offload-event-loop-dns
branch
from
July 20, 2026 15:08
08a5adc to
2a112b8
Compare
Exercise the enabled default resolver through the SOCKS bootstrap path from an AHC event loop. This verifies that proxy-host fallback DNS uses the configured resolver worker instead of blocking the event loop. Document the resolver helper and accessor as intentional public cross-package wiring while directing applications to the client config. Codex on behalf of Pavel Ptashyts Co-Authored-By: Codex <codex@openai.com>
pavel-ptashyts
force-pushed
the
perf/offload-event-loop-dns
branch
from
July 20, 2026 15:55
2a112b8 to
435e567
Compare
Contributor
Author
|
Closing by decision; performance-plan item 1.1 will be marked skipped. |
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.
Summary
NameResolverwhen resolution starts on a Netty event loopNameResolverimplementationsConfiguration
fallbackNameResolverOffloadEnableddefaults tofalseand must be enabled explicitlyfallbackNameResolverOffloadThreadsCountdefaults to-1, which uses the configured I/O thread countfallbackNameResolverOffloadQueueSizedefaults to0, which selects an automatic bounded capacityMotivation
The legacy fallback path uses Netty's JDK-backed
DefaultNameResolver. Redirect replays and SOCKS proxy bootstrap can enter that path from Netty event loops, so a cold or slow OS DNS lookup can block the loop.AddressResolverGroupusers remain on the existing asynchronous path, off-loop calls retain their current behavior, and custom resolvers are not moved to an unexpected thread.A bounded shared pool prevents an unbounded request backlog. Pending promises are tracked and failed when the pool rejects work or the client closes, including tasks removed from the queue by shutdown.
The resolver support classes are public only because client wiring crosses package boundaries. Applications should enable and tune the feature through
AsyncHttpClientConfig.Validation
./mvnw -pl client -am -Dtest='AddressResolverGroupTest#defaultSocksProxyResolverUsesOffloadPool' -Dsurefire.failIfNoSpecifiedTests=false test./mvnw -pl client -Dtest='AddressResolverGroupTest#defaultNameResolverOnRedirectUsesOffloadPool+defaultNameResolverOnRedirectKeepsInlineBehavior,AsyncHttpClientDefaultsTest#testDefaultFallbackNameResolverOffloadEnabled,NameResolverOffloadTest' test./mvnw -pl client -DskipTests -Dgpg.skip=true verifyAttribution
Codex on behalf of Pavel Ptashyts