Skip to content

feat(sdk-core): add sync HTTP-client warm-up to SdkWarmUp.prime() for CRaC priming#7080

Open
joviegas wants to merge 4 commits into
feature/master/crac_auto_priming_supportfrom
joviegas/crac_warmup_orchestration_partB
Open

feat(sdk-core): add sync HTTP-client warm-up to SdkWarmUp.prime() for CRaC priming#7080
joviegas wants to merge 4 commits into
feature/master/crac_auto_priming_supportfrom
joviegas/crac_warmup_orchestration_partB

Conversation

@joviegas

@joviegas joviegas commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Motivation and Context

This change adds the second half of the hybrid priming approach: one real GET per sync HTTP client on the classpath, so that network path is JIT-compiled into the CRaC snapshot. It also adds the region/endpoint resolution shared with the future async warm-up.

Modifications

SdkWarmUp.prime() now runs the per-service providers and then the HTTP-client warm-up, both inside the existing idempotency guard. The HTTP-client warm-up is best-effort: a network failure during init is logged and swallowed so the rest of priming completes.

New internal types in sdk-core:

  • RegionEndpointResolver (internal.crac): resolves the region from the aws.region system property, then AWS_REGION, then AWS_DEFAULT_REGION, then us-east-1, and builds https://sts.<region>.amazonaws.com/. It reads system properties and environment variables, and avoids the SDK region-resolution chain (IMDS, profile file) during priming. The region is URL-encoded into the host the same way Region.of(String) does.
  • SyncHttpClientWarmer (internal.http.loader): discovers every sync SdkHttpService through the existing package-private SdkServiceLoader, builds each client, sends the warm-up GET, drains the response body, and closes the client. It lives in this package because SdkServiceLoader is package-private.
  • WarmUpRequest: describes the warm-up request (a GET) and converts it to an SdkHttpRequest.
  • WarmUpDiscovery: the discover-and-iterate loop shared by the per-service and HTTP-client warm-up. It skips an element that fails to load or run, including LinkageError (a client jar present without its transitive dependencies), so one broken element does not stop the others.
  • HttpClientWarmer interface plus HttpWarmupInvoker / ClasspathHttpWarmupInvoker: prime() calls one invoker that owns the set of warmers. The async warmer is added to that set later without changing SdkWarmUp or SyncHttpClientWarmer.

Testing

Added Junits test

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • [x ] New feature (non-breaking change which adds functionality)

License

  • I confirm that this pull request can be released under the Apache 2 license

@joviegas joviegas requested a review from a team as a code owner June 26, 2026 00:08
@joviegas joviegas force-pushed the joviegas/crac_warmup_orchestration_partB branch 2 times, most recently from e4dfbde to 5b172b4 Compare June 26, 2026 15:17
@joviegas joviegas force-pushed the joviegas/crac_warmup_orchestration_partB branch from 5b172b4 to 82c723b Compare June 26, 2026 15:29
@joviegas joviegas force-pushed the joviegas/crac_warmup_orchestration_partB branch 2 times, most recently from bbf82e3 to 44b6b00 Compare June 26, 2026 16:43
public class Apache5HttpClientWarmUpTest {

@Rule
public WireMockRule mockServer = new WireMockRule(0);

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.

We have a test for each HTTP client instead of a shared suite in test/http-client-tests. A shared suite there would create a cyclic dependency, because sdk-core has test dependencies on apache-client and netty-nio-client (sdk-core -> apache-client -> http-client-tests -> sdk-core). I filed JAVA-9020 to refactor this on master; once fixed, these tests can move to test/http-client-tests as a single SyncHttpClientWarmUpTestSuite shared across all HTTP clients.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A separate centralized package would be great, but maybe we can have a dedicated test package for testing CRaC components instead of using http-client-tests

<version>${awsjavasdk.version}</version>
<scope>test</scope>
</dependency>
<dependency>

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.

@joviegas joviegas force-pushed the joviegas/crac_warmup_orchestration_partB branch from 44b6b00 to 2f5b864 Compare June 26, 2026 18:26
}

// AWS_DEFAULT_REGION is an environment-variable-only fallback with no system-property equivalent.
private static final class AwsDefaultRegionEnvVar implements SystemSetting {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AFAIK, we don't use AWS_DEFAULT_REGION for determining endpoints in the SDK (only DefaultsMode). Should we leave this out?

*/
public URI stsEndpoint() {
// URL-encode the region before putting it in the host, same as Region.of(String).
return URI.create("https://sts." + SdkHttpUtils.urlEncode(resolveRegion()) + ".amazonaws.com/");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

might benefit from using

public static void validateHostnameCompliant(String hostnameComponent, String paramName, String object) {
validateHostnameCompliant(hostnameComponent, paramName, object, DEFAULT_HOSTNAME_COMPLIANT_PATTERN);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

alternatively, build using the URI constructor will also validate it for correctness

Comment on lines +34 to +35
private final String body;
private final String contentType;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The ctor is private; are these necessary?

Comment on lines +29 to +30
* Resolves the regional STS endpoint ({@code https://sts.<region>.amazonaws.com/}) used by the CRaC HTTP-client warm-up.
*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this class intended to resolve other service endpoints in the future?

* matters for JIT priming.
*/
@SdkInternalApi
public final class WarmUpRequest {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not really sure about the usefulness of this class. Does it make more sense to just have a utility class/factory just creates the HttpExecuteRequest directly?

public class Apache5HttpClientWarmUpTest {

@Rule
public WireMockRule mockServer = new WireMockRule(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A separate centralized package would be great, but maybe we can have a dedicated test package for testing CRaC components instead of using http-client-tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants