Skip to content

fix(azcosmos): GetChangeFeed split-resilient via overlap match, 410/Gone retry, multi-range continuation queue (#26767)#26768

Merged
simorenoh merged 13 commits into
Azure:mainfrom
tvaron3:tvaron3/changefeed-split-handling
May 15, 2026
Merged

fix(azcosmos): GetChangeFeed split-resilient via overlap match, 410/Gone retry, multi-range continuation queue (#26767)#26768
simorenoh merged 13 commits into
Azure:mainfrom
tvaron3:tvaron3/changefeed-split-handling

Conversation

@tvaron3
Copy link
Copy Markdown
Member

@tvaron3 tvaron3 commented May 13, 2026

Closes #26767.

Purpose

ContainerClient.GetChangeFeed does not survive partition splits today. Three independent failure modes:

  1. Silent skip when the customer's FeedRange straddles new children. The legacy header builder exact-matched against the cached PK ranges via findPartitionKeyRangeID. After a split, the parent range no longer exactly equals any current child, so the request was issued without x-ms-documentdb-partitionkeyrangeid.
  2. Unrecoverable 410/Gone surfaces to the caller. GetChangeFeed propagated *azcore.ResponseError directly. The partitionKeyRangeCache.forceRefresh and maxPKRangeGoneRetries plumbing added in [Cosmos] add container cache and pk range cache #26723 was never wired into the change feed.
  3. Single-range continuation token. PopulateCompositeContinuationToken wrote one changeFeedRange. If the original FeedRange covered a parent that has since split, resume routed against a no-longer-physical EPK boundary instead of fanning out — events between calls were lost at the boundary.

There was also no cross-container guard: a token's ResourceID was never checked against the current container's _rid, so a wrong-container token would silently misroute against the wrong routing map.

What this change does

Wires GetChangeFeed to a queue-driven drain loop that mirrors the Java/.NET SDK behavior:

  • Overlap-match resolution. New overlappingPartitionKeyRanges + rangesOverlap helpers in cosmos_feed_range.go replace exact-match for routing decisions. Empty MaxExclusive is normalized to "FF".
  • Multi-range composite continuation token. New head/advance/replaceHeadWithChildren/dropHeadContinuation queue helpers on compositeContinuationToken. The composite token now describes the full set of unfinished sub-ranges; each entry is rotated FIFO with its own ETag.
  • Split expansion. When a single inbound range overlaps N children (post-split), the head is replaced with N entries, each inheriting the parent's ETag so no events are skipped at the boundary. If a queued sub-range splits mid-drain, the rotation budget is bumped so newly-inserted children are queried in the same call. The 410/Gone budget is reset on both split-expansion and head-advance so each newly-inserted physical head gets its own retry allowance.
  • 410/Gone retry with cache refresh. Bounded at maxPKRangeGoneRetries. The PK-range snapshot is fetched once per call (through the cache when present, falling back to a direct fetch) and reused across iterations; the 410 path re-fetches.
  • Cross-container ResourceID guard. A continuation token whose ResourceID differs from the current container's _rid is rejected loudly. The token's ResourceID is populated from the response body's _rid on first success so the guard remains meaningful across resume.
  • ErrFeedRangeUnresolved is returned (wrapped) when a customer-supplied FeedRange/token doesn't overlap any current physical range even after a forced refresh — a signal callers can errors.Is against and recover from rather than seeing an opaque error.
  • Pure buildRequestHeaders builder. New (head changeFeedRange, resolvedPKRangeID string) (map[string]string, error) builder. Returns an error when PartitionKey serialization fails so the caller can surface the cause instead of silently dropping the request (the original-bug pattern). The drain loop calls this with a pre-resolved head; the loop owns overlap-resolution upstream.
  • Cache-nil degraded fallback. When the PK-range cache is unavailable AND the direct fetch returns no ranges (test scaffolding only — production always wires up caches via acquireCaches), the loop logs a warning via log.Writef(azlog.EventResponse, ...), drops the head's continuation token, and reads fresh with a passthrough range so the request goes out without an x-ms-documentdb-partitionkeyrangeid header. Strict feedRangeUnresolvedError is preserved for genuine "FeedRange doesn't apply" cases.

The legacy ChangeFeedOptions.toHeaders and findPartitionKeyRangeID (the original-bug source) have been deleted. They were unexported and had no production callers after the rewrite. Coverage of the field-to-header mapping is preserved via cosmos_change_feed_request_options_test.go against the new buildRequestHeaders.

File organization

  • cosmos_container.go — public GetChangeFeed entrypoint stays here so the canonical container file continues to host the public API surface.
  • cosmos_container_change_feed.go (new)buildChangeFeedInitialQueue, resolveFeedRangeToChildren, buildChildQueueEntries, getChangeFeedForQueue (drain loop), serializeCompositeContinuationToken. Mirrors the cosmos_container_read_many.go split.
  • cosmos_change_feed_composite_continuation_token.go — queue-mutation helpers.
  • cosmos_change_feed_request_options.gobuildRequestHeaders (legacy toHeaders deleted).
  • cosmos_change_feed_response.godefer resp.Body.Close() ordering fix (above the 304 short-circuit).
  • cosmos_feed_range.gooverlappingPartitionKeyRanges, rangesOverlap, normalizeMaxBoundary.

Tests

Mock-based unit testscosmos_change_feed_split_test.go:

  • TestGetChangeFeed_410Gone_TriggersCacheRefreshAndRetry — 410 + cache-refresh + retry.
  • TestGetChangeFeed_RetryCapAt3_ReturnsLastErrorOnRepeated410 — surface final 410 after cap.
  • TestGetChangeFeed_TokenResourceIDMismatch_Rejected — cross-container guard.
  • TestGetChangeFeed_NoOverlapAfterRefresh_ReturnsErrFeedRangeUnresolved — loud-fail on unresolvable FeedRange.
  • TestGetChangeFeed_SplitExpansion_RoutesToFirstChild — child routing + persisted multi-range token.
  • TestGetChangeFeed_MultiRangeContinuation_RoundTrips — resume from a multi-element queue.
  • TestGetChangeFeed_SplitDuringDrain_QueriesEveryNewlyInsertedChild — regression guard for the rotation-budget bump.

Header-builder unit testscosmos_change_feed_request_options_test.go:

  • _BuildRequestHeaders_Defaults — empty options yields only the AIM header.
  • _BuildRequestHeaders_AllFields — every field maps to the right header.
  • _BuildRequestHeaders_EmptyContinuationOmitsIfNoneMatch — explicit empty ETag does not emit a stray IfNoneMatch.
  • _BuildRequestHeaders_PartitionKeySerializationError — verifies the new error-returning contract.

Emulator integration testsemulator_cosmos_change_feed_split_test.go (skipped when EMULATOR is unset):

  • _F1_SubRangeOfPhysicalRange — direct repro of the original bug (strict sub-range FeedRange).
  • _F1_WideRangeMultiDrain — paginate via composite token until all items across all physical ranges are drained.
  • _F1_CrossContainerTokenRejected — token from container A handed to container B is rejected.

The 3 pre-existing change-feed tests (TestContainerGetChangeFeedWithStartFrom, TestContainerGetChangeFeedWithStartFromFiltering, TestContainerGetChangeFeedForEPKRange) continue to pass.

go test -race -short -count=1 ./sdk/data/azcosmos/... is green. CI lint is green.

Three deep-reviewer rounds completed; the latest pass found no critical or should-fix issues.

Notes for reviewers

  • Token forward-compat: tokens issued by the old single-range writer still resume correctly (one queue entry → one head → drain loop runs once).
  • Token grows linearly with split count. A FeedRange that has straddled K splits will produce K queue entries in the persisted token. Acceptable for typical workloads; bounded by the physical-range fan-out.
  • response.FeedRange after split: when a customer FeedRange straddles a split, ChangeFeedResponse.FeedRange reports the head being drained for that page (not the original parent). Callers that previously relied on it round-tripping should use the persisted continuation token instead — noted in CHANGELOG.
  • Symbols used from [Cosmos] add container cache and pk range cache #26723: partitionKeyRangeCache, forceRefresh, maxPKRangeGoneRetries, isPKRangeGoneResponseError, ContainerClient.refreshPKRangeCache, ContainerClient.getContainerRID.

Checklist

…one retry, multi-range continuation queue (Azure#26767)

GetChangeFeed previously failed (silently or loudly) when a physical
partition split occurred under a customer-supplied FeedRange:

  * toHeaders did exact-equality matching against the cached PK ranges,
    so a parent FeedRange that no longer matched any current child fell
    through to a request issued WITHOUT the partition-key-range-id
    header (silent miss).
  * 410/Gone with the PartitionKeyRangeGone substatus surfaced directly
    to the caller; the underlying maxPKRangeGoneRetries / forceRefresh
    plumbing added in Azure#26723 was never wired into the change feed.
  * The composite continuation token only encoded a single EPK range,
    so resuming after a split lost events on the boundary.

This change rewires GetChangeFeed onto a queue-driven drain loop:

  * buildChangeFeedInitialQueue resolves the customer FeedRange (or
    inbound continuation token) by overlap-match against the routing
    map, expanding a parent FeedRange into N children inheriting the
    parent ETag.
  * getChangeFeedForQueue drains the queue FIFO. On each iteration it
    re-resolves the head against the cached snapshot, detects mid-drain
    splits and bumps the rotation budget so newly-inserted children
    get queried in the same call.
  * On 410/Gone with PK-range substatus, the cache is refreshed, the
    routing snapshot is re-fetched, and the head is retried; capped at
    maxPKRangeGoneRetries.
  * The composite continuation token now carries the full multi-range
    queue, with each entry's ETag advanced FIFO on every response.
  * Cross-container token reuse is rejected loudly: if a token's
    ResourceID does not match the current container's _rid, the call
    fails with a diagnostic error rather than silently misrouting
    against the wrong routing map.

Behavior preserved for callers without the cache infrastructure wired:
when no PK-range cache is present and the direct fetch returns no
ranges (test/mock case), a single passthrough queue entry is used so
the legacy issue-without-overlap-match flow still runs.

Tests added in cosmos_change_feed_split_test.go cover: 410-retry, retry
cap surfacing the final 410, cross-container ResourceID rejection,
no-overlap-after-refresh -> ErrFeedRangeUnresolved, split expansion
routing the first child, multi-range continuation round-trip, and the
mid-drain split-during-drain budget bump regression guard. All three
existing change-feed tests continue to pass.

Closes Azure#26767

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tvaron3 tvaron3 force-pushed the tvaron3/changefeed-split-handling branch from efb1e86 to c20a499 Compare May 13, 2026 23:01
tvaron3 and others added 7 commits May 13, 2026 23:11
…andling

- Capture drain-loop error in GetChangeFeed so deferred span observes failures (Azure#1)
- Reset 410/Gone budget on both split-expansion and head-advance (Azure#2)
- Move resp.Body.Close() above 304 short-circuit in newChangeFeedResponse (Azure#7)
- Drop dead empty-feedMax branch in cosmos_feed_range.go (Azure#8)
- Remove redundant token.head() reload in drain loop (Azure#9)
- Reduce buildChangeFeedInitialQueue to 3 returns (Azure#10)
- buildRequestHeaders surfaces PartitionKey serialization errors (Azure#11)
- Cache-nil + no-routing degraded fallback: log warning, drop continuation
  token, and read fresh with passthrough range instead of erroring; preserves
  back-compat for tests built without caches wired up
- CHANGELOG link points to PR

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Round-2 reviewer cleanup. dropHeadContinuation mutates Continuation[0]
in place; the existing head pointer reflects the change without reload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Condenses the GetChangeFeed numbered behavior list to a short paragraph
and trims the CHANGELOG entry. No behavior change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…itionKeyRangeID

- Move overlappingPartitionKeyRanges into cosmos_feed_range.go next to its
  sibling findOverlappingPartitionKeyRangeIDs and simplify to a single
  pass (no map round-trip)
- Delete the legacy ChangeFeedOptions.toHeaders builder and its test file;
  the new GetChangeFeed path uses buildRequestHeaders exclusively
- Delete the now-unused findPartitionKeyRangeID exact-match helper (the
  original silent-mismatch source); overlap-resolution lives upstream now
- Drop the small toHeaders-tail test in TestContainerGetChangeFeedWithStartFrom
  that only verified the legacy header builder

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t coverage

- Move GetChangeFeed, buildChangeFeedInitialQueue, resolveFeedRangeToChildren,
  buildChildQueueEntries, getChangeFeedForQueue, and serializeCompositeContinuationToken
  out of cosmos_container.go into cosmos_container_change_feed.go (mirrors the
  cosmos_container_read_many.go split). Pure relocation, no behavior change.
- Add cosmos_change_feed_request_options_test.go covering buildRequestHeaders:
  defaults (only AIM header), all-fields population, empty-ETag continuation
  is omitted, and PartitionKey serialization errors are surfaced (the new
  error-returning contract the legacy toHeaders silently swallowed).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three new emulator tests targeting F1-specific paths not covered by the
existing TestEmulatorContainerChangeFeed:

- SubRangeOfPhysicalRange — original-bug repro: a customer FeedRange that
  is a strict sub-range of a physical pkrange (no exact-match) must
  resolve via overlap-match and emit a request.
- WideRangeMultiDrain — wide FeedRange overlapping every physical range;
  paginates via the composite continuation token until all inserted items
  are drained, exercising the multi-range queue rotation.
- CrossContainerTokenRejected — token from container-A handed to
  container-B must be rejected by the ResourceID guard.

All three skip when EMULATOR is unset, matching repo convention.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Drop ineffectual headFeedRange reassignment in degraded fallback (it was
  never read after the assignment)
- Delete unused findOverlappingPartitionKeyRangeIDs (overlappingPartitionKeyRanges
  superseded it; no remaining callers)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tvaron3 tvaron3 marked this pull request as ready for review May 14, 2026 15:44
@tvaron3 tvaron3 requested a review from a team as a code owner May 14, 2026 15:44
Copilot AI review requested due to automatic review settings May 14, 2026 15:44
Helpers (buildChangeFeedInitialQueue, resolveFeedRangeToChildren,
buildChildQueueEntries, getChangeFeedForQueue, serializeCompositeContinuationToken)
remain in cosmos_container_change_feed.go; only the public method moves back
so the canonical container file continues to host the public API surface.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates sdk/data/azcosmos change feed paging/routing to be resilient to partition splits by resolving FeedRanges via overlap (instead of exact boundary match), expanding split parents into per-child work items, and retrying 410/Gone PK-range errors via cache refresh.

Changes:

  • Reworked ContainerClient.GetChangeFeed into a queue-driven drain loop that overlap-resolves ranges, expands splits, and performs bounded 410/Gone retries with PK-range cache refresh.
  • Added new helpers for overlap detection (overlappingPartitionKeyRanges, rangesOverlap, max-boundary normalization) and composite continuation queue operations (head/advance/replaceHeadWithChildren).
  • Added extensive unit tests for split/retry/token behavior plus new emulator coverage; updated request-header building tests and changelog.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
sdk/data/azcosmos/emulator_cosmos_change_feed_split_test.go Adds emulator tests validating overlap routing, multi-drain continuation, and cross-container token rejection.
sdk/data/azcosmos/cosmos_feed_range.go Introduces overlap-based PK range resolution helpers and ErrFeedRangeUnresolved.
sdk/data/azcosmos/cosmos_container.go Routes GetChangeFeed through the new queue-based implementation.
sdk/data/azcosmos/cosmos_container_test.go Removes a now-obsolete continuation/header assertion tied to the old toHeaders behavior.
sdk/data/azcosmos/cosmos_container_change_feed.go New change-feed drain loop implementation (queue, split expansion, 410 retry, token guard).
sdk/data/azcosmos/cosmos_change_feed_split_test.go New unit tests covering 410 retry, retry cap, split expansion, multi-range resume, and rotation budget bump.
sdk/data/azcosmos/cosmos_change_feed_response.go Ensures response bodies are closed even on 304 to avoid leaks during drain.
sdk/data/azcosmos/cosmos_change_feed_request_options.go Replaces legacy header builder with buildRequestHeaders for queue-head-based requests.
sdk/data/azcosmos/cosmos_change_feed_request_options_test.go Updates/expands tests to validate buildRequestHeaders behavior and error surfacing.
sdk/data/azcosmos/cosmos_change_feed_composite_continuation_token.go Adds composite continuation token queue helpers (head/advance/replaceHeadWithChildren).
sdk/data/azcosmos/CHANGELOG.md Documents the split-resilient GetChangeFeed fix.

Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
Comment thread sdk/data/azcosmos/CHANGELOG.md
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@kushagraThapar kushagraThapar left a comment

Choose a reason for hiding this comment

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

Hi @tvaron3, thank you for putting this together — I really enjoyed reading through the queue-driven drain loop and the way the 410/Gone retry budget resets across split-expansion. The three deep-reviewer rounds clearly show in the structural quality.

A few items below for your consideration. None of them are hard blockers IMO; the heaviest one is M-2 (cross-container _rid guard behavior on first-call 304) which I think is worth addressing in this PR. The rest are smaller correctness, testing, or documentation gaps.

A couple of items I'm planning to file as follow-up issues rather than block this PR:

  • The ChangeFeedWithStartTimePostMerge capability bit (pre-existing gap, not introduced here, but the new "split-resilient" framing makes it more customer-visible after a merge).
  • Two design-doc extension proposals for cosmosdb-design-docs (continuation-token container-identity invariant, and the FeedRange-becomes-unresolvable contract).

All comments are in the spirit of "could you please help me understand" rather than "must change" — happy to defer any of them if you have context I'm missing.

Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go Outdated
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go Outdated
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go Outdated
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go Outdated
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
@xinlian12
Copy link
Copy Markdown
Member

@sdkReviewAgent

Round-2 reviewer findings from kushagraThapar plus a CHANGELOG link revert:

- (Azure#2) Revert Copilot autofix that changed the CHANGELOG PR link from
  26768 (this PR) to 26767 (the issue it closes).
- (Azure#4) Clamp child ranges to the parent token's bounds during split-
  expansion (matches Java FeedRangeCompositeContinuationImpl.createChildRanges).
  Children that fall entirely outside the parent are dropped. New
  clampChildrenToParent helper + TestClampChildrenToParent.
- (Azure#5) Populate token.ResourceID at queue-construction time (both Path A
  and Path B) so the cross-container guard remains meaningful even when
  the very first response is a 304 (no body parsed).
- (Azure#6) Replace misleading 'legacy ETag-only continuation handled by
  buildRequestHeaders' comment with an accurate one stating that only
  composite tokens issued by GetChangeFeed are honored on resume; legacy
  raw-ETag continuation strings are not supported.
- (Azure#7) Surface partial drain state alongside the 410-budget-exhausted
  error so callers can resume from the failed head instead of re-querying
  drained heads. New TestGetChangeFeed_410BudgetExhaustedMidDrain_SurfacesPartialState.
- (Azure#8) Aggregate RequestCharge across drain iterations so the returned
  response reports total RU consumed (matches cosmos_container_read_many
  pattern).
- (Azure#9) Remove the cache-nil degraded fallback (production always wires
  caches via acquireCaches; the fallback existed only for legacy tests
  built without caches). Rewire the 3 legacy TestContainerGetChangeFeed*
  tests to use createChangeFeedTestClient with pre-seeded caches.
  Removes now-unused dropHeadContinuation helper.
- (Azure#10) Belt-and-suspenders: also accept len(response.Documents) > 0 in
  the early-return condition so a response missing _count but carrying
  docs isn't silently re-drained.
- (Azure#11) Add explicit ctx.Done() check at the top of the drain loop so a
  cancelled context exits between sub-requests rather than waiting for
  transport-level cancellation. New
  TestGetChangeFeed_ContextCancelled_HonoredBetweenSubRequests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
Comment thread sdk/data/azcosmos/cosmos_feed_range.go
Comment thread sdk/data/azcosmos/cosmos_container_change_feed.go
@xinlian12
Copy link
Copy Markdown
Member

Review complete (50:22)

Posted 3 inline comment(s).

Steps: ✓ context, correctness, cross-sdk, design, history, past-prs, synthesis, test-coverage

tvaron3 and others added 2 commits May 14, 2026 13:14
…split-handling

# Conflicts:
#	sdk/data/azcosmos/cosmos_container.go
…put options post-merge

- (X1) Add hard cap on drain-loop rotation budget (4*(initialLen+1))
  matching Java's FeedRangeCompositeContinuationImpl defense. Prevents
  unbounded loops if overlap-resolution ever produces duplicate ranges.
- (X2) Add focused table-driven unit tests for the overlap helpers:
  TestNormalizeMaxBoundary, TestRangesOverlap_TableDriven (10 cases),
  TestOverlappingPartitionKeyRanges_TableDriven (11 cases covering exact-
  match, multi-overlap, sub-range, straddling, empty/inverted/equal
  feed ranges, boundary touches).
- (X3) PopulateCompositeContinuationToken (public API) is now a no-op
  when ContinuationToken is already populated, preventing the multi-range
  composite token written by the drain loop from being overwritten with
  a stale single-range token rebuilt from the per-head FeedRange.

Post-merge with upstream/main (Azure#26750):
- Thread options.PriorityLevel and options.ThroughputBucket through the
  F1 drain loop's pipelineRequestOptions.headerOptionsOverride so the
  new priority/throughput-bucket support added in Azure#26750 reaches the
  change-feed request.
- Rewire TestChangeFeedPriorityAndThroughputBucketHeaders to use
  createChangeFeedTestClient (caches pre-wired) since the cache-nil
  fallback was removed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@kushagraThapar kushagraThapar left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @tvaron3

Copy link
Copy Markdown
Member

@FabianMeiswinkel FabianMeiswinkel left a comment

Choose a reason for hiding this comment

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

LGTM

@simorenoh simorenoh merged commit cead7f6 into Azure:main May 15, 2026
20 checks passed
tvaron3 added a commit that referenced this pull request May 15, 2026
…hangeFeedResponse (#26792)

* fix(azcosmos): remove no-op PopulateCompositeContinuationToken from ChangeFeedResponse

After PR #26768, GetChangeFeed populates ChangeFeedResponse.ContinuationToken
directly with the multi-range composite token. PopulateCompositeContinuationToken
became a no-op (early-returning when ContinuationToken was already set) to
prevent it from overwriting the multi-range token with a stale single-range
one rebuilt from the per-head FeedRange.

This PR removes the now-vestigial method outright. Tests that previously
exercised it have been retargeted at GetCompositeContinuationToken (which
still exists as a public helper for callers building single-range tokens
manually).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update sdk/data/azcosmos/CHANGELOG.md

Co-authored-by: Simon Moreno <30335873+simorenoh@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Simon Moreno <30335873+simorenoh@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Cosmos] azcosmos: GetChangeFeed silently loses data on partition split — no overlap-match, no 410/Gone retry, single-range continuation

6 participants