public async ValueTask InvokeAsync(IRequestContext context)
        {
            if (context.DocumentId is null)
            {
                await _next(context).ConfigureAwait(false);
            }
            else
            {
                bool   addToCache  = true;
                string?operationId = context.OperationId;

                if (operationId is null)
                {
                    operationId = context.Request.OperationName is null
                        ? context.DocumentId
                        : $"{context.DocumentId}+{context.Request.OperationName}";
                    context.OperationId = operationId;
                }

                if (_operationCache.TryGetOperation(
                        operationId,
                        out IPreparedOperation? operation))
                {
                    context.Operation = operation;
                    addToCache        = false;
                    _diagnosticEvents.RetrievedOperationFromCache(context);
                }

                await _next(context).ConfigureAwait(false);

                if (addToCache &&
                    context.Operation is { } &&
Exemplo n.º 2
0
        public async ValueTask InvokeAsync(IRequestContext context)
        {
            if (context.DocumentId is null)
            {
                await _next(context).ConfigureAwait(false);
            }
            else
            {
                var addToCache  = true;
                var operationId = context.OperationId;

                if (operationId is null)
                {
                    operationId = CreateOperationId(
                        context.DocumentId,
                        context.Request.OperationName);
                    context.OperationId = operationId;
                }

                string cacheId = context.CreateCacheId(operationId);

                if (_operationCache.TryGetOperation(cacheId, out IPreparedOperation? operation))
                {
                    context.Operation = operation;
                    addToCache        = false;
                    _diagnosticEvents.RetrievedOperationFromCache(context);
                }

                await _next(context).ConfigureAwait(false);

                if (addToCache &&
                    context.Operation is not null &&
                    context.DocumentId is not null &&
                    context.Document is not null &&
                    context.IsValidDocument)
                {
                    _operationCache.TryAddOperation(cacheId, context.Operation);
                    _diagnosticEvents.AddedOperationToCache(context);
                }
            }
        }
        public async Task AutoMerge_HotReload_ClearOperationCaches()
        {
            // arrange
            using var cts = new CancellationTokenSource(20_000);
            NameString         configurationName  = "C" + Guid.NewGuid().ToString("N");
            var                schemaDefinitionV2 = FileResource.Open("AccountSchemaDefinition.json");
            IHttpClientFactory httpClientFactory  = CreateDefaultRemoteSchemas(configurationName);
            DocumentNode       document           = Utf8GraphQLParser.Parse("{ foo }");
            var                queryHash          = "abc";

            IDatabase database = _connection.GetDatabase();

            while (!cts.IsCancellationRequested)
            {
                if (await database.SetLengthAsync(configurationName.Value) == 4)
                {
                    break;
                }

                await Task.Delay(150, cts.Token);
            }

            ServiceProvider serviceProvider =
                new ServiceCollection()
                .AddSingleton(httpClientFactory)
                .AddGraphQL()
                .AddQueryType(d => d.Name("Query").Field("foo").Resolve("foo"))
                .AddRemoteSchemasFromRedis(configurationName, _ => _connection)
                .Services
                .BuildServiceProvider();

            IRequestExecutorResolver executorResolver =
                serviceProvider.GetRequiredService <IRequestExecutorResolver>();
            IDocumentCache documentCache =
                serviceProvider.GetRequiredService <IDocumentCache>();
            IPreparedOperationCache preparedOperationCache =
                serviceProvider.GetRequiredService <IPreparedOperationCache>();

            await executorResolver.GetRequestExecutorAsync(cancellationToken : cts.Token);

            var raised = false;

            executorResolver.RequestExecutorEvicted += (_, args) =>
            {
                if (args.Name.Equals(Schema.DefaultName))
                {
                    raised = true;
                }
            };

            Assert.False(documentCache.TryGetDocument(queryHash, out _));
            Assert.False(preparedOperationCache.TryGetOperation(queryHash, out _));

            IRequestExecutor requestExecutor =
                await executorResolver.GetRequestExecutorAsync(cancellationToken : cts.Token);

            await requestExecutor
            .ExecuteAsync(QueryRequestBuilder
                          .New()
                          .SetQuery(document)
                          .SetQueryHash(queryHash)
                          .Create(),
                          cts.Token);

            Assert.True(preparedOperationCache.TryGetOperation("_Default-1-abc", out _));

            // act
            await database.StringSetAsync($"{configurationName}.{_accounts}", schemaDefinitionV2);

            await _connection.GetSubscriber().PublishAsync(configurationName.Value, _accounts);

            while (!cts.IsCancellationRequested)
            {
                if (raised)
                {
                    break;
                }

                await Task.Delay(150, cts.Token);
            }

            // assert
            Assert.True(documentCache.TryGetDocument(queryHash, out _));
            Assert.False(preparedOperationCache.TryGetOperation(queryHash, out _));
        }