Example #1
0
    private async ValueTask <List <object?> > CreateStreamResultAsync(
        StreamDirective streamDirective)
    {
        IAsyncEnumerable <object?> enumerable = Selection.CreateStream(_resolverContext.Result !);
        IAsyncEnumerator <object?> enumerator = enumerable.GetAsyncEnumerator();
        var next = true;

        try
        {
            var list         = new List <object?>();
            var initialCount = streamDirective.InitialCount;
            var count        = 0;

            if (initialCount > 0)
            {
                while (next)
                {
                    count++;
                    next = await enumerator.MoveNextAsync().ConfigureAwait(false);

                    list.Add(enumerator.Current);

                    if (count >= initialCount)
                    {
                        break;
                    }
                }
            }

            if (next)
            {
                // if the stream has more items than the initial requested items then we will
                // defer the rest of the stream.
                _operationContext.Scheduler.DeferredWork.Register(
                    new DeferredStream(
                        Selection,
                        streamDirective.Label,
                        _resolverContext.Path,
                        _resolverContext.Parent <object>(),
                        count - 1,
                        enumerator,
                        _resolverContext.ScopedContextData));
            }

            return(list);
        }
        finally
        {
            if (!next)
            {
                // if there is no deferred work we will just dispose the enumerator.
                // in the case we have deferred work, the deferred stream handler is
                // responsible of handling the dispose.
                await enumerator.DisposeAsync().ConfigureAwait(false);
            }
        }
    }
Example #2
0
    private async ValueTask ExecuteResolverPipelineAsync(CancellationToken cancellationToken)
    {
        await _resolverContext.ResolverPipeline !(_resolverContext).ConfigureAwait(false);

        if (_resolverContext.Result is null)
        {
            return;
        }

        if (_resolverContext.Result is IError error)
        {
            _resolverContext.ReportError(error);
            _resolverContext.Result = null;
            return;
        }

        // if we are not a list we do not need any further result processing.
        if (!Selection.IsList)
        {
            return;
        }

        if (Selection.IsStreamable)
        {
            StreamDirective streamDirective =
                Selection.SyntaxNode.Directives.GetStreamDirective(
                    _resolverContext.Variables) !;
            if (streamDirective.If)
            {
                _resolverContext.Result =
                    await CreateStreamResultAsync(streamDirective)
                    .ConfigureAwait(false);

                return;
            }
        }

        if (Selection.MaybeStream)
        {
            _resolverContext.Result =
                await CreateListFromStreamAsync()
                .ConfigureAwait(false);

            return;
        }

        switch (_resolverContext.Result)
        {
        case IExecutable executable:
            _resolverContext.Result = await executable
                                      .ToListAsync(cancellationToken)
                                      .ConfigureAwait(false);

            break;

        case IQueryable queryable:
            _resolverContext.Result = await Task.Run(() =>
            {
                var items = new List <object?>();
                foreach (var o in queryable)
                {
                    items.Add(o);

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                }

                return(items);
            }, cancellationToken);

            break;
        }
    }