Пример #1
0
        public async Task <ExecutionResult> Post([FromBody] GraphQLRequest request)
        {
            var queryNumber = Interlocked.Increment(ref _queryNumber);

            Console.WriteLine();
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(2, ' ')} - Running query {queryNumber}...");
            var sw = Stopwatch.StartNew();

            var result = await DataLoaderContext.Run(loadCtx => _executer.ExecuteAsync(_ =>
            {
                _.Schema      = _schema;
                _.Query       = request.Query;
                _.UserContext = new GraphQLUserContext(loadCtx);
            }));

            sw.Stop();

            var msg = result.Errors != null
                ? $"Error executing query {queryNumber}: {result.Errors.Aggregate("", (s, e) => s + Environment.NewLine + e.ToString())}"
                : $"Executed query {queryNumber} ({sw.ElapsedMilliseconds}ms)";

            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(2, ' ')} - {msg}");

            return(result);
        }
Пример #2
0
        private static Task <int> MultipleLoaderTask(DataLoaderContext context)
        {
            var task1 = context.GetOrCreateLoader(async token =>
            {
                await Task.Delay(20, token);
                return(4);
            }).LoadAsync();

            return(task1.ContinueWith(async t1 =>
            {
                var a = t1.Result;

                var task2 = context.GetOrCreateLoader(async token =>
                {
                    await Task.Delay(20, token);
                    return 5;
                }).LoadAsync();

                return await task2.ContinueWith(t2 =>
                {
                    var b = t2.Result;

                    return a + b;
                }, TaskContinuationOptions.None);
            }, TaskContinuationOptions.None).Unwrap());
        }
        public async Task TriggersConsecutiveLoads()
        {
            var loadCount = 0;

            await DataLoaderContext.Run(async ctx =>
            {
                var loader = ctx.GetOrCreateLoader <int, int>(
                    "somekey",
                    async ids =>
                {
                    await Task.Delay(100);
                    loadCount++;
                    return(ids.ToDictionary(id => id));
                });

                var one         = await loader.LoadAsync(1);
                var two         = await loader.LoadAsync(2);
                var three       = await loader.LoadAsync(3);
                var fourfivesix = await Task.WhenAll(
                    loader.LoadAsync(4),
                    loader.LoadAsync(5),
                    loader.LoadAsync(6)
                    );
            });

            loadCount.ShouldBe(4);
        }
        private async Task ExecuteAsync(HttpContext context, ISchema schema)
        {
            string body;

            using (var streamReader = new StreamReader(context.Request.Body))
            {
                body = await streamReader.ReadToEndAsync().ConfigureAwait(true);
            }

            var request = JsonConvert.DeserializeObject <GraphQLRequest>(body);

            var validationRules = new List <IValidationRule>()
            {
                new RequiresAuthValidationRule()
            };

            var result = await DataLoaderContext.Run(ctx => _executer.ExecuteAsync(_ =>
            {
                _.OperationName   = request.OperationName;
                _.Schema          = schema;
                _.Query           = request.Query;
                _.Inputs          = request.Variables.ToInputs();
                _.ValidationRules = validationRules.Concat(DocumentValidator.CoreRules());
                _.UserContext     = new GraphQLUserContext(ctx, context.User);
            }));

            await WriteResponseAsync(context, result);
        }
        public async Task DataLoaderContext_Run_FlowsCurrentContext()
        {
            var checkpoints = 0;

            await DataLoaderContext.Run(async() =>
            {
                var ctx = DataLoaderContext.Current;

                // Test with `Task.Yield`.
                await Task.Yield();
                DataLoaderContext.Current.ShouldBe(ctx);
                checkpoints++; // 1

                // Test with `Task.Delay`.
                await Task.Delay(100);
                DataLoaderContext.Current.ShouldBe(ctx);
                checkpoints++; // 2

                // Test with `Task.Run`.
                await Task.Run(() => DataLoaderContext.Current.ShouldBe(ctx));
                checkpoints++; // 3

                // Test with `Thread`.
                var thread = new Thread(() =>
                {
                    DataLoaderContext.Current.ShouldBe(ctx);
                    checkpoints++; // 4
                });
                thread.Start();
                thread.Join();
            });

            checkpoints.ShouldBe(4);
        }
        public async Task FlowsLikeSyncContext()
        {
            var checkpoints = 0;

            await DataLoaderContext.Run(async _ =>
            {
                var ctx = DataLoaderContext.Current;

                // Should flow over `Task.Yield`
                await Task.Yield();
                DataLoaderContext.Current.ShouldBe(ctx);
                checkpoints++; // 1

                // Should flow over `Task.Delay`
                await Task.Delay(100);
                DataLoaderContext.Current.ShouldBe(ctx);
                checkpoints++; // 2

                // Shouldn't flow into Task.Run
                await Task.Run(() => DataLoaderContext.Current.ShouldBe(null));
                DataLoaderContext.Current.ShouldBe(ctx);
                checkpoints++; // 3

                // Shouldn't flow into a new Thread
                var thread = new Thread(() => { DataLoaderContext.Current.ShouldBe(null); });
                thread.Start();
                thread.Join();
                DataLoaderContext.Current.ShouldBe(ctx);
                checkpoints++; // 4
            });

            checkpoints.ShouldBe(4);
        }
Пример #7
0
        public async Task DataLoaderContext_Run_AllowsParallelContexts()
        {
            const int n        = 2;
            var       barrier  = new Barrier(n);
            var       contexts = new ConcurrentBag <DataLoaderContext>();

            Func <Task> action = async() =>
            {
                await DataLoaderContext.Run(ctx =>
                {
                    barrier.SignalAndWait();
                    ctx.ShouldBe(DataLoaderContext.Current);
                    contexts.Add(DataLoaderContext.Current);
                    return(Task.FromResult(1));
                });
            };

            var t1 = Task.Run(action);
            var t2 = Task.Run(action);

            await Task.WhenAll(t1, t2);

            contexts.Count.ShouldBe(n);
            contexts.ShouldBeUnique();
        }
Пример #8
0
 private static Task <int> SingleLoaderTask(DataLoaderContext context)
 => context.GetOrCreateLoader(token =>
                              Task.Run(() =>
 {
     Thread.Sleep(7);
     return(7);
 }, token)).LoadAsync();
        public async Task It_loads_with_context()
        {
            var expectedResult  = "data";
            var expectedContext = new DataLoaderContext();

            expectedContext["key1"] = "value1";

            var context = default(IDataLoaderContext);

            var dataLoader = DataLoaderBuilder <string>
                             .Empty
                             .WithName(nameof(It_loads_with_context))
                             .WithLoadMethod(async(ct, request) =>
            {
                context = request.Context;

                return(expectedResult);
            })
                             .Build();

            var cancellationToken = CancellationToken.None;

            var result = await dataLoader.Load(cancellationToken, expectedContext);

            result.Should().Be(expectedResult);
            context.Should().BeEquivalentTo(expectedContext);
        }
Пример #10
0
        private static async Task RefreshDataLoader(CancellationToken ct, IDataLoader dataLoader)
        {
            var context = new DataLoaderContext();

            context["IsForceRefreshing"] = true;

            await dataLoader.Load(ct, context);
        }
 public async Task SetsCurrent()
 {
     await DataLoaderContext.Run(() =>
     {
         DataLoaderContext.Current.ShouldNotBeNull();
         return(Task.CompletedTask);
     });
 }
Пример #12
0
        public void DataLoader_ReflectsCurrentContext()
        {
            var loader = new DataLoader <object, object>(_ => null);

            loader.Context.ShouldBeNull();
            DataLoaderContext.Run(ctx => { loader.Context.ShouldBe(ctx); return(Task.CompletedTask); });
            loader.Context.ShouldBeNull();
        }
        public void SetData(object data)
        {
            var context = new DataLoaderContext(new Dictionary <string, object>
            {
                { DataContextKey, data },
            });

            RaiseLoadRequested(context);
        }
Пример #14
0
 public Task <ExecutionResult> DataLoader()
 {
     _dataLoaderOptions.UserContext = _userContext;
     return(DataLoaderContext.Run(loadCtx =>
     {
         _userContext.LoadContext = loadCtx;
         return _executer.ExecuteAsync(_dataLoaderOptions);
     }));
 }
        public void SetError(Exception error)
        {
            var context = new DataLoaderContext(new Dictionary <string, object>
            {
                { ErrorContextKey, error },
            });

            RaiseLoadRequested(context);
        }
        public async Task DataLoaderContext_Run_UnsetsCurrent()
        {
            var task = DataLoaderContext.Run(() => {});

            DataLoaderContext.Current.ShouldBeNull();
            await task;

            DataLoaderContext.Current.ShouldBeNull();
        }
Пример #17
0
 public Loaders(IDataLoaderContextAccessor loadContextAccessor, IBranchSettingsAccessor branchSettings, IUserPermissionAccessor permissionAccessor, IRemoteRepositoryState repositoryState, IBranchIterationNamingConvention branchIteration, IGitServiceApi gitService, ILoggerFactory loggerFactory)
 {
     this.logger             = loggerFactory.CreateLogger <Loaders>();
     this.loadContext        = loadContextAccessor.LoadContext;
     this.branchSettings     = branchSettings;
     this.permissionAccessor = permissionAccessor;
     this.repositoryState    = repositoryState;
     this.branchIteration    = branchIteration;
     this.gitService         = gitService;
 }
Пример #18
0
        public async Task Complete_SingleLoaderTask_ShouldNotBlock()
        {
            var context = new DataLoaderContext();
            var task    = SingleLoaderTask(context);
            await context.Complete(CancellationToken.None);

            var result = await task;

            Assert.That(result, Is.EqualTo(7));
        }
Пример #19
0
        public async Task Complete_MultipleLoaderTask_ShouldNotBlock()
        {
            var context = new DataLoaderContext();
            var task    = MultipleLoaderTask(context);
            await context.Complete(CancellationToken.None);

            var result = await task.ConfigureAwait(false);

            Assert.That(result, Is.EqualTo(9));
        }
Пример #20
0
        public async Task <TransactionCode[]> Codes(
            [Inject] DataLoaderContext dataLoaderContext,
            [Inject] OutputTypesMapperResolver mapperResolver,
            [Inject] ITransactionRepository repository)
        {
            IEnumerable <Models.TransactionCode> codes = await dataLoaderContext
                                                         .GetOrAddCollectionBatchLoader <Guid, Models.TransactionCode>(nameof(repository.GetTransactionCodesInBatch), repository.GetTransactionCodesInBatch)
                                                         .LoadAsync(Id);

            return(mapperResolver().Map <TransactionCode[]>(codes));
        }
Пример #21
0
        public async Task <FinancialYear> FinancialYear(
            [Inject] DataLoaderContext dataLoaderContext,
            [Inject] OutputTypesMapperResolver mapperResolver,
            [Inject] IFinancialYearRepository repository)
        {
            Entities.FinancialYear financialYear = await dataLoaderContext
                                                   .GetOrAddBatchLoader <Guid, Entities.FinancialYear>(nameof(repository.GetFinancialYearsInBatch), repository.GetFinancialYearsInBatch)
                                                   .LoadAsync(FinancialYearId);

            return(mapperResolver().Map <FinancialYear>(financialYear));
        }
Пример #22
0
        public async Task Complete_WithOneDataLoader_ShouldCallExecuteAsyncMethod()
        {
            var token          = new CancellationTokenSource().Token;
            var context        = new DataLoaderContext();
            var dataLoaderMock = new Mock <IExecutableDataLoader>();

            (context as IDataLoaderContext).QueueExecutableDataLoader(dataLoaderMock.Object);
            await context.Complete(token);

            dataLoaderMock.Verify(x => x.ExecuteAsync(token), Times.Once);
        }
Пример #23
0
        public async Task Complete_WithMultipleDataLoaders_ShouldCallAllExecuteAsyncMethods()
        {
            var token           = new CancellationTokenSource().Token;
            var context         = new DataLoaderContext();
            var dataLoaderMocks = Enumerable.Range(0, 20).Select(_ => new Mock <IExecutableDataLoader>()).ToList();

            dataLoaderMocks.ForEach(mock => (context as IDataLoaderContext).QueueExecutableDataLoader(mock.Object));
            await context.Complete(token);

            dataLoaderMocks.ForEach(mock => mock.Verify(x => x.ExecuteAsync(token), Times.Once));
        }
        public DataLoaderQueryHandlerWrapperTests()
        {
            queryHandler = new Mock <IQueryHandler <IQuery, string> >();
            var dataLoaderContextAccessorMock = new Mock <IDataLoaderContextAccessor>();

            target = new DataLoaderQueryHandlerWrapper <IQuery, string>(
                loaderKey,
                queryHandler.Object,
                dataLoaderContextAccessorMock.Object);

            dataLoaderContext = new DataLoaderContext();
            dataLoaderContextAccessorMock.Setup(e => e.Context).Returns(dataLoaderContext);
        }
        public async Task DataLoaderContext_Run_SetsCurrentContext()
        {
            DataLoaderContext.Current.ShouldBeNull();

            await DataLoaderContext.Run(ctx =>
            {
                DataLoaderContext.Current.ShouldBe(ctx);
                DataLoaderContext.Current.ShouldNotBeNull();
                return(Task.CompletedTask);
            });

            DataLoaderContext.Current.ShouldBeNull();
        }
Пример #26
0
        static void Main(string[] args)
        {
            var pipeline = new PipeLine <DataLoaderContext>()
                           .AddStep(new LoadDataStep())
                           .AddStep(new SendMessageStep());

            var context = new DataLoaderContext {
                CorrelationContextId = Guid.NewGuid()
            };

            var result = pipeline.Execute(context);

            Console.ReadKey();
        }
        /// <summary>
        /// Get or add a DataLoader instance for caching data fetching operations.
        /// </summary>
        /// <typeparam name="T">The type of data to be loaded</typeparam>
        /// <param name="context">The <seealso cref="DataLoaderContext"/> to get or add a DataLoader to</param>
        /// <param name="loaderKey">A unique key to identify the DataLoader instance</param>
        /// <param name="fetchFunc">A delegate to fetch data asynchronously</param>
        /// <returns>A new or existing DataLoader instance</returns>
        public static IDataLoader <T> GetOrAddLoader <T>(this DataLoaderContext context, string loaderKey, Func <Task <T> > fetchFunc)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (fetchFunc == null)
            {
                throw new ArgumentNullException(nameof(fetchFunc));
            }

            return(context.GetOrAdd(loaderKey, () => new SimpleDataLoader <T>(WrapNonCancellableFunc(fetchFunc))));
        }
Пример #28
0
 public Task <ExecutionResult> Execute(GraphQLQuery query)
 {
     return(DataLoaderContext.Run(loadCtx =>
     {
         serviceProvider.GetRequiredService <DataLoaderContextStore>().LoadContext = loadCtx;
         var executionOptions = new ExecutionOptions
         {
             Schema = schema,
             Query = query.Query,
             Inputs = GetInputs(query.Variables),
             UserContext = serviceProvider,
         };
         return documentExecuter.ExecuteAsync(executionOptions);
     }));
 }
        public async Task CanBeNested()
        {
            await DataLoaderContext.Run(async outerCtx =>
            {
                await DataLoaderContext.Run(async innerCtx =>
                {
                    innerCtx.ShouldNotBe(outerCtx);
                    innerCtx.ShouldBe(DataLoaderContext.Current);
                    await Task.Yield();
                    innerCtx.ShouldBe(DataLoaderContext.Current);
                });

                DataLoaderContext.Current.ShouldBe(outerCtx);
            });
        }
 public async Task DataLoaderContext_Run_CanBeNested()
 {
     await DataLoaderContext.Run(async outerCtx =>
     {
         DataLoaderContext.Current.ShouldBe(outerCtx);
         var task = DataLoaderContext.Run(innerCtx =>
         {
             innerCtx.ShouldNotBe(outerCtx);
             innerCtx.ShouldBe(DataLoaderContext.Current);
         });
         DataLoaderContext.Current.ShouldBe(outerCtx);
         await task;
         DataLoaderContext.Current.ShouldBe(outerCtx);
     });
 }