Пример #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);
        }
        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);
        }
        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);
        }
Пример #4
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();
        }
        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);
        }
        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 SetsCurrent()
 {
     await DataLoaderContext.Run(() =>
     {
         DataLoaderContext.Current.ShouldNotBeNull();
         return(Task.CompletedTask);
     });
 }
Пример #8
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();
        }
Пример #9
0
 public Task <ExecutionResult> DataLoader()
 {
     _dataLoaderOptions.UserContext = _userContext;
     return(DataLoaderContext.Run(loadCtx =>
     {
         _userContext.LoadContext = loadCtx;
         return _executer.ExecuteAsync(_dataLoaderOptions);
     }));
 }
        public async Task DataLoaderContext_Run_UnsetsCurrent()
        {
            var task = DataLoaderContext.Run(() => {});

            DataLoaderContext.Current.ShouldBeNull();
            await task;

            DataLoaderContext.Current.ShouldBeNull();
        }
        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();
        }
        public async Task <ExecutionResult> Post([FromBody] GraphQLRequest request)
        {
            var watch = Stopwatch.StartNew();

            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} - Executing GraphQL query");

            var result = await DataLoaderContext.Run(loadCtx =>
                                                     _executer.ExecuteAsync(_schema, null, request.Query, null, userContext: new GraphQLUserContext {
                LoadContext = loadCtx
            }));

            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} - Finished query ({watch.ElapsedMilliseconds}ms)");

            return(result);
        }
Пример #13
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);
     });
 }
        public void CanBeCancelled()
        {
            var cts = new CancellationTokenSource();

            cts.CancelAfter(50);

            var didRun = false;
            var task   = DataLoaderContext.Run(async token =>
            {
                didRun = true;
                await Task.Delay(300, token);
            }, cts.Token);

            didRun.ShouldBeTrue();
            task.ShouldThrow <TaskCanceledException>();
        }
        public void RespectsAlreadyCancelledToken()
        {
            var cts = new CancellationTokenSource();

            cts.Cancel();

            var didRun = false;
            var task   = DataLoaderContext.Run(token =>
            {
                didRun = true;
                return(null);
            }, cts.Token);

            didRun.ShouldBe(false);
            task.IsCanceled.ShouldBe(true);
        }
Пример #18
0
        public async Task DataLoader_WithoutBoundContext_ReflectsCurrentContext()
        {
            var loader = new DataLoader <object, object>(_ => null);

            loader.Context.ShouldBeNull();
            var task = DataLoaderContext.Run(async ctx =>
            {
                loader.Context.ShouldBe(ctx);
                await Task.Delay(200);
                loader.Context.ShouldBe(ctx);
            });

            loader.Context.ShouldBeNull();
            await task;

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

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

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

            sw.Stop();
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(2, ' ')} - Executed query {queryNumber} ({sw.ElapsedMilliseconds}ms)");
            return(result);
        }
        public async Task DataLoaderContext_Run_CanBeNested()
        {
            await DataLoaderContext.Run(async outerCtx =>
            {
                DataLoaderContext.Current.ShouldBe(outerCtx);

                await DataLoaderContext.Run(innerCtx =>
                {
                    innerCtx.ShouldNotBe(outerCtx);
                    innerCtx.ShouldBe(DataLoaderContext.Current);
                    return(Task.CompletedTask);
                });

                DataLoaderContext.Current.ShouldBe(outerCtx);
            });

            DataLoaderContext.Current.ShouldBeNull();
        }
        public void DataLoaderContext_Run_TriggersConsecutiveLoads()
        {
            var loadCount = 0;

            var loader = new DataLoader <int, int>(async ids =>
            {
                await Task.Delay(150);
                loadCount++;
                return(ids.ToLookup(id => id));
            });

            var task = DataLoaderContext.Run(async() =>
            {
                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)
                    );

                var t7 = loader.LoadAsync(7);
                var t8 = loader.LoadAsync(8);
                var t9 = loader.LoadAsync(9);
                Thread.Sleep(200);

                var ten = await loader.LoadAsync(10);

                t7.IsCompleted.ShouldBeTrue();
                t8.IsCompleted.ShouldBeTrue();
                t9.IsCompleted.ShouldBeTrue();

                return(true);
            });

            Should.CompleteIn(task, TimeSpan.FromSeconds(10));
            loadCount.ShouldBe(5);
        }
        public async Task HandlesUnrelatedAwaits()
        {
            var loadCount = 0;

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

                var one = await loader.LoadAsync(1);
                await Task.Delay(50);
                var two = await loader.LoadAsync(2);
            });

            loadCount.ShouldBe(2);
        }
        public void DataLoaderContext_Run_AllowsParallelContexts()
        {
            const int n        = 2;
            var       barrier  = new Barrier(n);
            var       contexts = new ConcurrentBag <DataLoaderContext>();

            Action <int> action = _ =>
            {
                DataLoaderContext.Run(ctx =>
                {
                    barrier.SignalAndWait();
                    ctx.ShouldBe(DataLoaderContext.Current);
                    contexts.Add(DataLoaderContext.Current);
                    return(Task.FromResult(1));
                }).Wait();
            };

            var result = Parallel.For(0, n, action);

            result.IsCompleted.ShouldBeTrue();
            contexts.Count.ShouldBe(n);
            contexts.ShouldBeUnique();
        }
        public async Task DataLoaderContext_Run_FlowsCurrentContext()
        {
            await DataLoaderContext.Run(async() =>
            {
                var ctx      = DataLoaderContext.Current;
                var threadId = Thread.CurrentThread.ManagedThreadId;

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

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

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

                // Test with `Thread`.
                var thread = new Thread(() => DataLoaderContext.Current.ShouldBe(ctx));
                thread.Start();
                thread.Join();
            });
        }
        public async Task UnsetsCurrent()
        {
            await DataLoaderContext.Run(() => Task.CompletedTask);

            DataLoaderContext.Current.ShouldBeNull();
        }
        public async Task DataLoaderContext_Run_SetsCurrent()
        {
            await DataLoaderContext.Run(() => DataLoaderContext.Current.ShouldNotBeNull());

            await DataLoaderContext.Run(ctx => DataLoaderContext.Current.ShouldBe(ctx));
        }