diff --git a/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Services/SerialDocumentExecuter.cs b/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Services/SerialDocumentExecuter.cs new file mode 100644 index 00000000000..17c964634af --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Services/SerialDocumentExecuter.cs @@ -0,0 +1,36 @@ +using GraphQL; +using GraphQL.Execution; +using GraphQL.Language.AST; +using System; + +namespace OrchardCore.Apis.GraphQL.Services +{ + /// + /// Defines a custom execution strategy for queries such that async lambdas are not executed in parallel. + /// c.f. https://github.com/OrchardCMS/OrchardCore/issues/3029 + /// + public class SerialDocumentExecuter : DocumentExecuter + { + private static IExecutionStrategy ParallelExecutionStrategy = new ParallelExecutionStrategy(); + private static IExecutionStrategy SerialExecutionStrategy = new SerialExecutionStrategy(); + private static IExecutionStrategy SubscriptionExecutionStrategy = new SubscriptionExecutionStrategy(); + + protected override IExecutionStrategy SelectExecutionStrategy(ExecutionContext context) + { + switch (context.Operation.OperationType) + { + case OperationType.Query: + return SerialExecutionStrategy; + + case OperationType.Mutation: + return SerialExecutionStrategy; + + case OperationType.Subscription: + return SubscriptionExecutionStrategy; + + default: + throw new InvalidOperationException($"Unexpected OperationType {context.Operation.OperationType}"); + } + } + } +} diff --git a/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Startup.cs index 1083c6b6b1c..cc67b0209dd 100644 --- a/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Apis.GraphQL/Startup.cs @@ -29,7 +29,7 @@ public Startup(IShellConfiguration configuration, public override void ConfigureServices(IServiceCollection services) { services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddScoped();