Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sdk/data/azcosmos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

### Breaking Changes

* Removed `ChangeFeedResponse.PopulateCompositeContinuationToken()`. The method is no longer needed: `GetChangeFeed` now populates `ChangeFeedResponse.ContinuationToken` directly with the multi-range composite token. Callers who built single-range tokens manually can use `GetCompositeContinuationToken()` instead.
Comment thread
tvaron3 marked this conversation as resolved.
Outdated

### Bugs Fixed

* Fixed `GetChangeFeed` to survive partition splits: customer-supplied `FeedRange`s are now overlap-matched against the routing map, `410/Gone` triggers a cache refresh and bounded retry, split parents expand into per-child queue entries (inheriting the parent's ETag), and the continuation token persists multi-range state across calls. Continuation tokens are guarded against cross-container reuse. See [PR 26768](https://github.com/Azure/azure-sdk-for-go/pull/26768).
Expand Down
21 changes: 0 additions & 21 deletions sdk/data/azcosmos/cosmos_change_feed_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,27 +59,6 @@ func newChangeFeedResponse(resp *http.Response) (ChangeFeedResponse, error) {
return response, nil
}

// PopulateCompositeContinuationToken generates and sets the composite continuation
// token from response.FeedRange + response.ETag. Retained for back-compat.
//
// In the multi-range queue-driven GetChangeFeed path, response.ContinuationToken
// is already populated with the multi-range composite token by the drain loop
// itself. This method is therefore a no-op when ContinuationToken is non-empty
// — overwriting it with a single-range token rebuilt from the per-head
// FeedRange would lose the multi-range queue state and cause callers that
// resume with the resulting token to skip subsequent ranges after a split.
func (response *ChangeFeedResponse) PopulateCompositeContinuationToken() {
if response.ContinuationToken != "" {
return
}
if response.FeedRange != nil && response.ETag != "" {
compositeToken, err := response.GetCompositeContinuationToken()
if err == nil && compositeToken != "" {
response.ContinuationToken = compositeToken
}
}
}

// GetContinuation from ChangeFeedResponse
func (c ChangeFeedResponse) GetContinuation() string {
return string(c.ETag)
Expand Down
22 changes: 13 additions & 9 deletions sdk/data/azcosmos/cosmos_change_feed_response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,16 @@ func TestChangeFeedResponseWithFeedRange(t *testing.T) {
MaxExclusive: "FF",
}

parsedResponse.PopulateCompositeContinuationToken()

if parsedResponse.ContinuationToken == "" {
t.Fatal("expected CompositeContinuationToken to be populated, but it was empty")
tokenStr, err := parsedResponse.GetCompositeContinuationToken()
if err != nil {
t.Fatalf("GetCompositeContinuationToken returned error: %v", err)
}
if tokenStr == "" {
t.Fatal("expected GetCompositeContinuationToken to return a non-empty token")
}

var compositeToken compositeContinuationToken
err = json.Unmarshal([]byte(parsedResponse.ContinuationToken), &compositeToken)
err = json.Unmarshal([]byte(tokenStr), &compositeToken)
if err != nil {
t.Fatalf("failed to unmarshal composite token: %v", err)
}
Expand Down Expand Up @@ -211,9 +213,11 @@ func TestChangeFeedResponseWithoutFeedRange(t *testing.T) {
t.Fatalf("failed to create ChangeFeedResponse: %v", err)
}

parsedResponse.PopulateCompositeContinuationToken()

if parsedResponse.ContinuationToken != "" {
t.Errorf("expected CompositeContinuationToken to be empty, but got: %q", parsedResponse.ContinuationToken)
tokenStr, err := parsedResponse.GetCompositeContinuationToken()
if err != nil {
t.Fatalf("GetCompositeContinuationToken returned error: %v", err)
}
if tokenStr != "" {
t.Errorf("expected GetCompositeContinuationToken to return empty string when FeedRange is nil, got: %q", tokenStr)
}
}
3 changes: 1 addition & 2 deletions sdk/data/azcosmos/cosmos_container_change_feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,7 @@ func (c *ContainerClient) getChangeFeedForQueue(
// Capture the response body's _rid into the token's ResourceID on first
// successful response. This keeps the cross-container guard meaningful
// across resume — token-issued-by-this-container always carries the
// container's RID — and matches pre-F1 PopulateCompositeContinuationToken
// semantics that downstream tests rely on.
// container's RID.
if token.ResourceID == "" && response.ResourceID != "" {
token.ResourceID = response.ResourceID
}
Expand Down