DynamoDbResolveEndpointInterceptor re-evaluates endpoint rules engine on every request even when endpointOverride is static
- 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