aws / aws/aws-sdk-java-v2

DynamoDbResolveEndpointInterceptor re-evaluates endpoint rules engine on every request even when endpointOverride is static

Aperta
#6,847 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Java
Stelle
2.6k
Fork
1k
Merge medio
2g 9h
PR unite (30g)
51

Descrizione

## Summary

When `DynamoDbClientBuilder.endpointOverride(uri)` is configured, the resolved endpoint is static for the lifetime of the client. However, `DynamoDbResolveEndpointInterceptor.modifyRequest()` still calls `DefaultDynamoDbEndpointProvider.resolveEndpoint()` on every single request, which re-evaluates the full endpoint rules engine and re-parses the URI from scratch each time.

## Evidence

Using async-profiler on a JanusGraph server with a DynamoDB-heavy read workload (Query-dominated, ~thousands of DynamoDB calls/sec, SDK version **2.42.28**):

- `DynamoDbResolveEndpointInterceptor.modifyRequest`: **1.97% cumulative CPU** of total JVM CPU
- `java/net/URI$Parser.scan`: **0.36% flat CPU** — URI re-parsed on every request
- `DefaultDynamoDbEndpointProvider.resolveEndpoint()` runs the full rules engine even when the endpoint was statically configured

This is a subset of the broader `AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext` overhead (6.44% total).

## Workaround

Bypassing `endpointOverride` in favor of a custom `endpointProvider` lambda that returns a pre-built static `Endpoint` eliminates this per-request cost entirely:

```java
URI resolvedEndpoint = URI.create("https://dynamodb.us-east-1.amazonaws.com");
Endpoint staticEndpoint = Endpoint.builder().url(resolvedEndpoint).build();

DynamoDbClient.builder()
.endpointProvider(params -> CompletableFuture.completedFuture(staticEndpoint))
// ... rest of config
.build();
```

This saves ~0.5% CPU on our workload. The workaround is not obvious and shouldn't be required — `endpointOverride` is a documented, common configuration pattern.

## Proposed fix

When `endpointOverride` is set at client construction time, the `DynamoDbResolveEndpointInterceptor` (or the underlying `DefaultDynamoDbEndpointProvider`) should cache the resolved `Endpoint` after the first evaluation and return the cached result on subsequent requests. Since the endpoint override URI is immutable after construction, this is safe.

Alternatively, the interceptor could detect at construction time that `endpointOverride` is present and substitute a no-op/cached implementation.

## Relationship to PR #6820

PR #6820 ("Move endpoint resolution from interceptors to pipeline stage") addresses this architecturally. This issue is filed to track the specific user-visible problem — static `endpointOverride` causing per-request endpoint rules evaluation — in case the PR takes time to land or a targeted fix is preferred.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia con DynamoDbResolveEndpointInterceptor.modifyRequest() e DefaultDynamoDbEndpointProvider.resolveEndpoint(), quindi esamina il percorso endpointOverride e la PR #6820 per il contesto correlato. Verifica che un client con un endpointOverride statico non rivaluti il motore delle regole né analizzi nuovamente l’URI a ogni richiesta, mantenendo corretta la risoluzione dell’endpoint.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
java
Ambito
backend, performance
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.