Closed annelo-msft closed 4 days ago
Tagging subscribers to this area: @dotnet/area-system-collections See info in area-owners.md if you want to be subscribed.
Is there any expectation to ever use these new base system types to also represent paged data from OData services?
@xuzhg @habbes
Is there any expectation to ever use these new base system types to also represent paged data from OData services?
These types are intended for use with System.ClientModel-based clients, and such clients can talk to cloud services that use OData in their APIs. I don't know that there is an expectation that they would be used outside the SCM-based client context, but if they are useful outside of that context, I don't know of reasons not to use them. One limitation might be that they are currently scoped to HTTP given the dependency on SCM's PipelineResponse.
The additions would still live in the Azure SDK repo and the NuGet package correct?
I set the milestone to 10.0.0 since we're currently in the process on bringing down our issue numbers for .NET 9 endgame. Are you looking to get this reviewed soon?
Can you help me better understand ContinuationToken? What does someone do with the bytes when handed an arbitrary token? Seems like a given token instance would only make sense to the API set that produced it? Do the bytes-related APIs even need to be part of the base type? Or are these bytes the rehydration mechanism you referred to, such that they're exposed purely so they can be persisted and then used to reconstitute a token? And if that's the case, the ctor that takes bytes doesn't need to be public?
Can you help me better understand ContinuationToken?
Yes, good questions, and glad to get your eyes on this area.
This type was designed to satisfy the following constraints:
byte[]
to work well with ASP.NET IDistributedCache APIsTo satisfy 3, the intended use for this type is that clients will create internal subtypes of ContinuationToken
specific to a service method for a paginated service endpoint. An example is MessagesPageToken. It can create itself from either bytes or a runtime instance when passed to a client method, for example GetMessages.
I looked at using only BinaryData
instead of adding a new ContinuationToken
type, but this would have required always writing the bytes of a token to create a PageResult<T>
instance, even though paying that perf cost would be needed in only a small percentage of use cases.
What does someone do with the bytes when handed an arbitrary token?
I put a snip from a sample ASP.NET app above, but the primary use case is to be able to resume paging from processes behind a load balancer. One process can cache a byte[]
from a page token and another can retrieve the byte[]
and recreate the collection from its current state by doing something like:
assistantClient.GetAssistants(ContinuationToken.FromBytes(cachedPageTokenBytes));
Seems like a given token instance would only make sense to the API set that produced it?
That is correct. A client should throw if an instance is passed to a service method that can't be used to create the correct internal token type.
Do the bytes-related APIs even need to be part of the base type? Or are these bytes the rehydration mechanism you referred to, such that they're exposed purely so they can be persisted and then used to reconstitute a token?
Yes, the latter. These APIs allow us to defer writing the runtime type to bytes until a user opts-in to the "rehydration" scenario by calling ToBytes
.
And if that's the case, the ctor that takes bytes doesn't need to be public?
I think it does, since the operation-specific types the client is using are internal.
(All of that said, if you see ways to improve these APIs, I am always open to making the product better!)
As a side note, we also plan to use ContinuationToken
to implement rehydration scenarios for the SCM long-running operation type that is forthcoming.
Thanks!
That makes sense. Thanks for keeping us in the loop. Since we don't have any change requests, we'll close this as completed.
Background and motivation
Overview
The System.ClientModel library provides building blocks for .NET clients that call cloud services. System.ClientModel 1.0.0 has types for reading and writing message content, reviewed as part of https://github.com/dotnet/runtime/issues/94126, and System.ClientModel 1.1.0-beta.2 added end-user convenience types and client-author pipeline types, reviewed as part of https://github.com/dotnet/runtime/issues/97711.
In this iteration of the System.ClientModel API, we would like to add types to enable clients to provide service methods to retrieve collections of items from paginated endpoints and streaming endpoints.
Page Collection Types
Cloud services use pagination to return a collection of items over multiple responses. Each response from the service returns a page of items in the collection, as well as the information needed to obtain the next page of items, until all the items in the requested collection have been returned. There are two primary client-user scenarios for this category of service methods: enumerating all the items of the requested collection (independent of the paged delivery mechanism) and rendering a single page of results. In addition to these primary scenarios, there is a requirement that the collection must be able to be "rehydrated," i.e. continued from a process different from the one that originally created the collection. The rehydration requirement means that we must be able to persist the collection state and separately recreate the collection from the persisted state.
To enable clients to provide service methods for paginated endpoints, we would like to add
PageCollection<T>
,AsyncPageCollection<T>
,PageResult<T>
andContinuationToken
types as described below.Streaming Collection Types
Cloud services such as OpenAI and Azure OpenAI use SSE streams to deliver incremental updates sequentially over a single response stream. We would like to add
CollectionResult<T>
andAsyncCollectionResult<T>
types to System.ClientModel to provide a convenience layer over the SseParser types in theSystem.Formats.Sse
namespace. This will enable clients to provide service methods that return collections of model types and from which the raw HTTP response details can also be obtained.API Proposal
API Usage
Example usage of
AsyncCollectionResult<T>
with OpenAI chat completions operation:Example usage of `AsyncPageCollection with OpenAI list assistants operation:
Sample usage of
PageResult<T>
in ASP.NET web app "collection rehydration" scenario:A full implementation of a mock paging client can be found here.
Alternative Designs
No response
Risks
No response