Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Preview] Change Feed: Add FeedRange and continuation separate #1355

Merged
merged 170 commits into from
Apr 20, 2020

Conversation

ealsur
Copy link
Member

@ealsur ealsur commented Apr 8, 2020

This PR applies a refactoring on the existing FeedToken concept plus, adds support for Queries.

Replacing FeedToken for FeedRange + Continuation

This change conceptually decouples the range represented by a FeedToken from the continuation. A FeedRange now simply represents a Range of partition key values and nothing more. This range could be matching a complete physical partition, a smaller range, or a single partition key value.

Task<IReadOnlyList<FeedRange>> Container.GetFeedRangesAsync(CancellationToken cancellationToken = default(CancellationToken));

provides a way to obtain the list of ranges, very much like FeedToken previously (see #1210).

Separating FeedRange from Continuation provides two major benefits:

  1. A FeedRange is now valid to be used for a Change Feed operation or for a Query.
  2. The concept of Continuation Token as a string is more familiar to our users than having to learn how to acquire and serialize (and then deserialize) the FeedToken.

Change Feed

Most of the functionality from the previous Change Feed using FeedToken remains the same with some slight changes.

Iterator

Change Feed is an infinite feed, but we detect the case where no more changes are pending to be read through the HasMoreResults flag:

FeedIterator iterator = container.GetChangeFeedStreamIterator();
string continuation = null;
while (iterator.HasMoreResults)
{
    // Stream iterator returns a response with status code
    using(ResponseMessage response = await iterator.ReadNextAsync())
    {
       // consume message
       continuation = response.ContinuationToken;
    }
}

// Means no more changes in the Change Feed

// Some time later, we can check for new changes
ChangeFeedIterator iterator = container.GetChangeFeedStreamIterator(continuation);

Parallelization

IReadOnlyList<FeedRange> ranges = await container.GetFeedRangesAsync();

// Machine or Thread 1
FeedIterator iteratorForToken = container.GetChangeFeedStreamIterator(ranges[0]);
while (iteratorForToken.HasMoreResults)
{
    // Stream iterator returns a response with status code
    using(ResponseMessage response = await iteratorForToken .ReadNextAsync())
    {
        if(response.IsSuccessStatusCode)
        {
            // Consume response.Content stream
        }
    }
}

// Machine or Thread 2
FeedIterator iteratorForToken = container.GetChangeFeedStreamIterator(ranges[1]);
while (iteratorForToken.HasMoreResults)
{
    // Stream iterator returns a response with status code
    using(ResponseMessage response = await iteratorForToken .ReadNextAsync())
    {
        if(response.IsSuccessStatusCode)
        {
            // Consume response.Content stream
        }
    }
}

Consume the entire Container

Scenario is exactly as it was for FeedToken:

FeedIterator iteratorForTheEntireContainer = container.GetChangeFeedStreamIterator();
while (iteratorForTheEntireContainer.HasMoreResults)
{
    // Stream iterator returns a response with status code
    using(ResponseMessage response = await iteratorForTheEntireContainer.ReadNextAsync())
    {
        if(response.IsSuccessStatusCode)
        {
            // Consume response.Content stream
        }
    }
}

Change Feed for a Partition Key

Same scenario as with FeedTokens, it's an overload of the GetChangeFeedStreamIterator or GetChangeFeedIterator:

FeedIterator iteratorForTheEntireContainer= container.GetChangeFeedStreamIterator(new PartitionKey("myPartitionKeyValueToRead");

Diagnostics

Added Diagnostics information to show which was the FeedRange used for a particular Change Feed request.

image

Read Feed

Previously we were using the same FeedIteratorCore implementation for non-partitioned (metadata) resources and partitioned (documents) resources with conditional logic.

This PR leaves the FeedIteratorCore class for non-partitioned resources, while adding FeedRangeIteratorCore for partitioned resources with explicit logic to handle FeedRanges and keep supporting parallelization of ReadFeed operations (introduced on #1230). The key here is the introduction of FeedRangeResponseMessage that wraps ResponseMessage and promotes the continuation format for FeedRange on ResponseMessage.Continuation.

Same concepts of parallelization through FeedRange are maintained in this refactoring.

Queries

This PR adds new APIs for Queries to take FeedRange as an input parameter. This effectively scopes the query to the defined Range.

public abstract FeedIterator GetItemQueryStreamIterator(
            FeedRange feedRange,
            QueryDefinition queryDefinition,
            string continuationToken = null,
            QueryRequestOptions requestOptions = null);

public abstract FeedIterator<T> GetItemQueryIterator<T>(
            FeedRange feedRange,
            QueryDefinition queryDefinition,
            string continuationToken = null,
            QueryRequestOptions requestOptions = null);

Once the scope is set and the query is executed, continuation is used the same way as a normal query flow (capture from the Response/FeedResponse if loop needs to be stopped). The continuation is valid for the FeedRange used.

Removed APIs

Scaling a FeedToken has been removed.

Closing issues

This PR closes #1228.
This PR closes #1262.
This PR closes #1226.
This PR closes #1225.
This PR closes #1241

@ealsur ealsur merged commit bf3cc6a into master Apr 20, 2020
@ealsur ealsur deleted the users/ealsur/feedtokenplusct branch April 20, 2020 21:02
@ealsur ealsur mentioned this pull request Apr 20, 2020
1 task
j82w added a commit that referenced this pull request Apr 21, 2020
* [Internal] Documentation: Fix text on retry builder extension (#1388)

* Autoscale: Fix ThroughputProperties factory names (#1392)

* Changed CreateFixedOffer to CreateManualOffer to matcht the portal

* Updated contract docs

* Fixed contract to use preview version

* CreateAutoscaleProvionedThroughput to CreateAutoscaleThroughput

* Removed redundant throughput

* Updated naming again

* Update contract

* Client Encryption : Add nuget info to Encryption csproj and compile against preview SDK (#1385)

* Add nuget info to Encryption csproj and compile against preview SDK

* Remove SourceLink related property unless we need it at first go

* Encryption versioning independent of client

* Set 3.8.0-preview as minimum client version that would be referenced by Encryption assembly

* Add back PREVIEW constant

* Internal Query: Add logic to execute some queries as Passthrough when possible (#1319)

* added passthrough code path

* added another condition

* added some sanity tests

* moved passthrough creation into pipeline

* added test injections to observe whether the query is passthrough or not

* missed case where query has top, order by, offset limit

* resolved iteration comments

* fixed nullable check

* fixed typo

* [Preview] Change Feed: Add FeedRange and continuation separate (#1355)

FeedRange and continuation separate

* [Internal] Pipeline: Add Microsoft.Azure.Cosmos.Encryption release pipeline (#1403)

* encryption pipeline

* removing cred check

* Fix path

* Apply suggestions from code review

Co-Authored-By: j82w <[email protected]>

Co-authored-by: j82w <[email protected]>

* [Internal] Direct Version: Add direct version 3.9.0 (#1398)

* Bump direct version 3.9.0

* [Internal] Documentation: Add notes and test for memory optimization (#1399)

* add test for memorybuffer

* changelog

* Diagnostics: Add CPU monitoring for .Net Core (#1400)

* [Internal] Diagnostics: Add Cpu monitoring for .Net Core

* [Internal] Diagnostics: Add Cpu monitoring for .Net Core CI test coverage

* Diagnostics: Add Cpu monitoring for .Net Core

Diagnostics: Add Cpu monitoring for .Net Core

* [Internal]: Diagnostics: Fix for unit tests to address code review comments

* Diagnostics: Add CPU monitoring for .Net Core (#1402)

* [Internal] Diagnostics: Add Cpu monitoring for .Net Core

* [Internal] Diagnostics: Add Cpu monitoring for .Net Core CI test coverage

* Diagnostics: Add Cpu monitoring for .Net Core

Diagnostics: Add Cpu monitoring for .Net Core

* [Internal]: Diagnostics: Fix for unit tests to address code review comments

* Update changelog.md

Co-authored-by: Matias Quaranta <[email protected]>
Co-authored-by: Fabian Meiswinkel <[email protected]>

* Fixed changelog and updated api

Co-authored-by: Matias Quaranta <[email protected]>
Co-authored-by: abhijitpai <[email protected]>
Co-authored-by: Brandon Chong <[email protected]>
Co-authored-by: Fabian Meiswinkel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request New feature or request
Projects
None yet
6 participants