Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[cosmos] Hedging Detection API — public accessors on CosmosDiagnostics + CosmosDiagnosticsContext

Abierto
#49,182 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

  • #49184 de @NaluTripician — cerrado sin fusionar

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
java

Línea de trabajo

Comienza con los cambios indicados en CosmosDiagnostics.java, CosmosDiagnosticsContext.java y ClientSideRequestStatistics.java; después, rastrea los puntos de entrada de la estrategia de disponibilidad en RxDocumentClientImpl y los archivos de retry-policy. Ejecuta primero RequestedRegionTests.java y HedgingDetectionTests.java; después verifica los criterios de aceptación, la instantánea de APIView y la suite de regresión del conector de Spark; la tarea requiere que todos los accessors solicitados, el seguimiento, la agregación y las pruebas pasen correctamente.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Client Cosmos needs-team-attention Service Attention

Summary

Add a public Hedging Detection API to com.azure.cosmos.CosmosDiagnostics and com.azure.cosmos.CosmosDiagnosticsContext so customers can post-hoc determine whether a successful or failed Cosmos point/feed operation went through cross-region hedging, which regions were dispatched against, and which regions responded. The surface is strictly additive and non-breaking — both CosmosDiagnostics and CosmosDiagnosticsContext are final, so additions are non-breaking by construction.

This is part of a cross-SDK feature being implemented in parallel across .NET, Java, and Python (with a spec-only deliverable for Rust). See cross-SDK design doc "Hedging Detection API - Technical Design - Final" (2026-05) for the contract.

Public API additions

package com.azure.cosmos.models;

public final class RequestedRegion {
    public RequestedRegion(String regionName, RequestedRegionReason reason); // null-guards on regionName
    public String getRegionName();
    public RequestedRegionReason getReason();
    @Override public boolean equals(Object o);
    @Override public int hashCode();
    @Override public String toString(); // "<regionName>:<REASON>"
}

public enum RequestedRegionReason {
    INITIAL,
    OPERATION_RETRY,
    TRANSPORT_RETRY,           // reserved
    HEDGING,
    REGION_FAILOVER,
    CIRCUIT_BREAKER_PROBE,     // tied to upstream PRs #45197 / #45267 / #46477 / #48421
}
package com.azure.cosmos;

public final class CosmosDiagnostics {
    // existing members unchanged
    public boolean isHedgingStarted();
    public List<RequestedRegion> getRequestedRegions(); // unmodifiable snapshot
    public List<String>         getRespondedRegions(); // unmodifiable snapshot, arrival order, duplicates allowed
}

public final class CosmosDiagnosticsContext {
    // existing members unchanged
    public boolean isHedgingStarted();                  // aggregates across children
    public List<RequestedRegion> getRequestedRegions(); // aggregates across children (same pattern as getContactedRegionNames)
    public List<String>          getRespondedRegions(); // aggregates across children
}

Internal state lives on ClientSideRequestStatistics: private final Object regionLock = new Object(); + List<RequestedRegion> requestedRegions + List<String> respondedRegions + boolean hedgingStarted. All three guarded by the same lock — reads AND writes acquire the lock so any reader observes both writes or neither. Bridge accessor ImplementationBridgeHelpers.CosmosDiagnosticsAccessor gains a single appendRequestedRegion(diag, entry) method whose implementation writes both the entry and (if reason == HEDGING) sets hedgingStarted = true inside synchronized(stats.regionLock). setHedgingStarted is not a separate bridge surface — the compound-atomicity invariant is enforced from the bridge.

Critical: Reactor operator order

Append the HEDGING entry via .doOnSubscribe(...) attached inside the hedge arm's Mono chain, NOT before Mono.delaySubscription. Operator order matters:

// CORRECT — doOnSubscribe is on the upstream of delaySubscription
Mono<Response> hedgeArm = regionalMono
    .doOnSubscribe(s -> bridgeAccessor.appendRequestedRegion(
        diag, new RequestedRegion(region, RequestedRegionReason.HEDGING)))
    .delaySubscription(threshold, scheduler);

// WRONG — would fire before the delay starts (phantom entry on primary-wins-under-threshold)
Mono<Response> hedgeArm = regionalMono
    .delaySubscription(threshold, scheduler)
    .doOnSubscribe(s -> bridgeAccessor.appendRequestedRegion(...));

This is the design doc §12 "no phantom entries" contract — see AC2 / AC10.

Acceptance criteria (testable)

  • AC1 Single-region client, readItem success, no retries → isHedgingStarted() == false; getRequestedRegions().size() == 1 with reason INITIAL; getRespondedRegions().size() == 1.
  • AC2 Multi-region client, hedging enabled (ThresholdBasedAvailabilityStrategy), primary responds under threshold → isHedgingStarted() == false; getRequestedRegions().size() == 1; no phantom HEDGING entry.
  • AC3 Multi-region client, hedging enabled, primary slow, hedge arm wins → isHedgingStarted() == true; getRequestedRegions() has ≥2 entries including (hedgeRegion, HEDGING); getRespondedRegions() has ≥1 entry.
  • AC4 410 Gone retry on same region → getRequestedRegions() includes consecutive entries (region, INITIAL) then (region, OPERATION_RETRY).
  • AC5 Region failover after endpoint failure → getRequestedRegions() includes (originalRegion, INITIAL) then (secondaryRegion, REGION_FAILOVER).
  • AC6 All-regions-down error → CosmosException.getDiagnostics().getRequestedRegions() non-empty.
  • AC9 Existing EndToEndTimeOutWithAvailabilityTest.getContactedRegionNames().size() > 1 (:117) and all 33+ assertions in FaultInjectionWithAvailabilityStrategyTests.java continue to pass.
  • AC10 Reactor scheduler / cancellation smoke test — assert (a) .doOnSubscribe() on each hedge arm fires only after delaySubscription elapses without cancellation; (b) when the primary completes before delaySubscription elapses, the hedge arm's Mono is cancelled and .doOnSubscribe() does NOT fire; (c) when .doOnSubscribe() does fire, the append happens on the orchestrator-side scheduler.
  • AC11 Aggregation — CosmosDiagnosticsContext.getRequestedRegions() returns the FIFO-ordered union across the ConcurrentLinkedDeque<CosmosDiagnostics> children.
  • AC12 Spark connector regression — azure-cosmos-spark_3-4_2-12 test suite passes locally.
  • AC13 APIView snapshot diff cleanly shows the additions (no removals; no signature drift).
  • AC14 Live multi-region smoke test (≥1) — runs against the team's multi-region test account with hedging enabled (ThresholdBasedAvailabilityStrategy), injects primary-slow latency via fault-injection, and asserts isHedgingStarted() == true, getRequestedRegions() includes both regions with the secondary tagged HEDGING, getRespondedRegions() includes the secondary region.

Files in scope

  • New: sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/models/RequestedRegion.java, RequestedRegionReason.java
  • Modify: CosmosDiagnostics.java, CosmosDiagnosticsContext.java, ClientSideRequestStatistics.java (state + @JsonIgnore on new fields — Spark / encryption / Kafka-connect deserialize through this class), ImplementationBridgeHelpers.java (bridge accessor extension), RxDocumentClientImpl.wrapPointOperationWithAvailabilityStrategy:5460 + executeFeedOperationWithAvailabilityStrategy:5850, ClientRetryPolicy.refreshLocation / shouldRetryOnEndpointFailureAsync (:245, :298), GoneAndRetryWithRetryPolicy.java:33/:90, PPCB hook (rebase on PRs #45197 / #45267 / #46477 / #48421), sdk/cosmos/azure-cosmos/CHANGELOG.md
  • Tests: new RequestedRegionTests.java, new HedgingDetectionTests.java, live-account multi-region test

Out of scope

  • Wiring into OpenTelemetry — separate work item.
  • Spark connector behavioral changes — only the @JsonIgnore defensive annotation lands here.
  • Cross-SDK companion implementations (.NET, Python, Rust) — tracked in companion issues.

Notes for the implementer

  • Full internal spec, landscape research, plan, risk register (side-effects.json), and questions+answers are available from the workflow author (@NaluTripician) on request — they are team-only and not linked here.
  • Phase 1 review gate completed on 2026-05-14. Java-specific resolved decisions: shared regionLock pattern (matches .NET / Python); single bridge accessor appendRequestedRegion (no separate setHedgingStarted); com.azure.cosmos.models placement for new public types (matches CosmosItemResponse / FeedResponse precedent); at least one live multi-region smoke test required.
  • This issue is being dispatched to the Coding Agent Harness for end-to-end implementation; reviewers may receive a draft PR shortly.
Lenguaje dominante
Java
Estrellas
2.6k
Forks
2.2k
Merge medio
1 d 18 h
PR fusionados (30 d)
231

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Azure/azure-sdk-for-java

Todos los issues de Azure/azure-sdk-for-java

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.