Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

オープン
#49,182 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

  • #49184 @NaluTripician による — マージされずにクローズ

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
35/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
静か
技術スタック
java

調査の方向性

CosmosDiagnostics.java、CosmosDiagnosticsContext.java、ClientSideRequestStatistics.java に記載された変更から始め、次に RxDocumentClientImpl の availability strategy のエントリポイントと retry-policy ファイルを追跡します。まず RequestedRegionTests.java と HedgingDetectionTests.java を実行し、その後、受け入れ条件、APIView snapshot、Spark connector の回帰テストスイートを検証します。完了とするには、要求されたすべての accessor、tracking、aggregation、およびテストがパスする必要があります。

索引モデルが issue の本文から書いたものです。

説明

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.
主要言語
Java
スター
2.6k
フォーク
2.2k
平均マージ
1日 18時間
マージ済み PR(30日)
206

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Azure/azure-sdk-for-java のほかの issue

Azure/azure-sdk-for-java の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。