Connect client entity SDK to gRPC service.#185
Connect client entity SDK to gRPC service.#185sebastianburckhardt merged 12 commits intofeature/entitiesfrom
Conversation
Co-authored-by: Jacob Viau <javia@microsoft.com>
| /// Gets the continuation token to continue the <see cref="CleanEntityStorageRequest"/>, if not null. | ||
| /// </summary> | ||
| public int OrphanedLocksRemoved { get; init; } | ||
| public string? ContinuationToken { get; init; } |
There was a problem hiding this comment.
Do we want to expose this to customers? Or do we want to abstract away the continuation behavior? As in, the gRPC protocol and implementation will handle continuation under the hood, only returning when it has exhausted continuations.
If you feel continuation must be exposed, we should at least offer an extension method or something that will loop through continuation. I wouldn't want every time a customer uses this API for them to have to include a while loop.
There was a problem hiding this comment.
There are some situations where exposing the continuation is desirable (e.g. user is running a durable orchestration to perform an extremely-long-running operation, so it can resume gracefully if interrupted).
But yeah, for the common case we do want to have the automatically-continuing one.
There was a problem hiding this comment.
I have added an optional argument to control whether the query should always continue until complete, or return a partial result with a continuation token.
There was a problem hiding this comment.
I'll approve for now, but still not super happy with this.
I wonder if a custom IAsyncEnumerable<CleanEntityStorageResult>-esque type is the appropriate way? Then going one by one is as simple as iteration over the enumerable. Or going over all of them is an AggregateAsync()
So it would be a type like:
public abstract class AggregateRequest<TResult>
{
public abstract Task<TResult?> NextAsync(); // make a single call
public abstract Task<TResult?> AllAsync(); // invoke all of them
}Just a thought, can be done at a later time (but before GA at least)
There was a problem hiding this comment.
Yeah, I was also first considering something like AsyncPageable or AsyncEnumerable. However, I decided against it because I can really only see two common ways in which I expect this would be used (1) do all the work at once and wait for the final result (I expect this to be the most common so it should be the easiest to use) (2) do only one page (if users want to persist intermediate progress). For neither of those it provides significant value to return a pageable or enumerable result.
There was a problem hiding this comment.
This isn't blocking for the PR. We can think about it more later.
| /// Gets the continuation token to continue the <see cref="CleanEntityStorageRequest"/>, if not null. | ||
| /// </summary> | ||
| public int OrphanedLocksRemoved { get; init; } | ||
| public string? ContinuationToken { get; init; } |
There was a problem hiding this comment.
I'll approve for now, but still not super happy with this.
I wonder if a custom IAsyncEnumerable<CleanEntityStorageResult>-esque type is the appropriate way? Then going one by one is as simple as iteration over the enumerable. Or going over all of them is an AggregateAsync()
So it would be a type like:
public abstract class AggregateRequest<TResult>
{
public abstract Task<TResult?> NextAsync(); // make a single call
public abstract Task<TResult?> AllAsync(); // invoke all of them
}Just a thought, can be done at a later time (but before GA at least)
# Conflicts: # eng/proto
Provides the glue to connect the entity client features to the gRPC service
TaskHubSidecarService.