cognite-sdk-dotnet icon indicating copy to clipboard operation
cognite-sdk-dotnet copied to clipboard

Feature Request: Queries that return IAsyncEnumerable To Iterate Through Cursors

Open bbrandt opened this issue 2 years ago • 4 comments

Please provide either an extension method to convert ItemsWithCursor<T> to an IAsyncEnumerable<T> for any method or another set of methods for each query returning a cursor such as

public async IAsyncEnumerable<TimeSeries> ListAllAsync(TimeSeriesQuery query, [EnumeratorCancellation] CancellationToken token = default)

bbrandt avatar Aug 16 '22 17:08 bbrandt

Examples: https://stackoverflow.com/a/67317050/5167537 https://martendb.io/documents/querying/linq/async-enumerable.html

bbrandt avatar Aug 16 '22 17:08 bbrandt

My completely untested attempt in my layer wrapping the Cognite SDK:

        public static async IAsyncEnumerable<TResult> AsAsyncEnumerable<TResult, TQuery>(
            Func<TQuery, CancellationToken, Task<ItemsWithCursor<TResult>>> listAsync,
            TQuery query,
            [EnumeratorCancellation] CancellationToken token)
            where TQuery : CursorQueryBase
        {
            var itemsWithCursor = await listAsync(query, token);
            foreach (var item in itemsWithCursor.Items)
            {
                yield return item;
            }

            while (!string.IsNullOrEmpty(itemsWithCursor.NextCursor))
            {
                query.Cursor = itemsWithCursor.NextCursor;

                itemsWithCursor = await listAsync(query, token);

                foreach (var item in itemsWithCursor.Items)
                {
                    yield return item;
                }
            }
        }

        public IAsyncEnumerable<TimeSeries> ListAllAsync(TimeSeriesQuery query, CancellationToken token = default)
        {
            return AsAsyncEnumerable(ListAsync, query, token);
        }

Feel free to sprinkle in your own F#/Oryx magic. https://github.com/fsprojects/FSharp.Control.AsyncSeq https://github.com/fsprojects/FSharp.Control.AsyncSeq/issues/96

bbrandt avatar Aug 16 '22 18:08 bbrandt

Thanks for the tag, @polomani. Can you give a bit more detail around what would be expected from a PR from the community? Does the implementation need to follow the current pattern of being written in Oryx with F# and having a thin C# wrapper around it or would we be good with a C#-only implementation in this case?

bbrandt avatar Aug 18 '22 14:08 bbrandt

@bbrandt I assume your use-case requires C#? In that case, feel free to make a pure c# implementation. We can then move this into Oryx when we feel a need.

polomani avatar Aug 22 '22 09:08 polomani