Skip to content

Rework concurrency gate for subscriptions#9580

Merged
michaelstaib merged 5 commits intomainfrom
mst/retooled-concurrency-gate
Apr 20, 2026
Merged

Rework concurrency gate for subscriptions#9580
michaelstaib merged 5 commits intomainfrom
mst/retooled-concurrency-gate

Conversation

@michaelstaib
Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings April 19, 2026 13:11
@github-actions github-actions Bot added 📚 documentation This issue is about working on our documentation. 🌶️ hot chocolate labels Apr 19, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reworks concurrency limiting to operate at the GraphQL execution level (rather than HTTP request level), and extends the gate consistently to subscription handshakes and per-event executions across Hot Chocolate Core and Fusion.

Changes:

  • Introduces ExecutionConcurrencyGate plus a ConcurrencyGateMiddleware and wires it into the default execution pipelines.
  • Updates subscription execution paths (Core + Fusion) so each subscription event also acquires/releases a concurrency slot.
  • Renames server option from MaxConcurrentRequests to MaxConcurrentExecutions, removes the old ASP.NET Core transport-level gate, and updates docs/tests accordingly.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md Adds migration docs for the new execution-level concurrency gate.
website/src/docs/fusion/v16/performance-tuning.md Updates Fusion perf docs to describe execution-based concurrency limiting and new option name.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Pipeline/FusionMiddleware.cs Exposes the shared concurrency gate middleware config for Fusion pipelines.
src/HotChocolate/Fusion/src/Fusion.Execution/Execution/OperationPlanExecutor.cs Gates subscription event processing with ExecutionConcurrencyGate.
src/HotChocolate/Fusion/src/Fusion.Execution/DependencyInjection/CoreFusionGatewayBuilderExtensions.Pipeline.cs Adds UseConcurrencyGate() and inserts it into Fusion default pipelines.
src/HotChocolate/Fusion/src/Fusion.AspNetCore/DependencyInjection/FusionServerServiceCollectionExtensions.cs Registers per-schema ExecutionConcurrencyGate based on named GraphQLServerOptions.
src/HotChocolate/Core/test/Execution.Tests/Pipeline/ConcurrencyGateMiddlewareTests.cs Adds extensive tests for pipeline/event gating behavior and timeout semantics.
src/HotChocolate/Core/src/Types/Execution/Processing/SubscriptionExecutor.cs Passes an optional gate into the subscription execution path.
src/HotChocolate/Core/src/Types/Execution/Processing/SubscriptionExecutor.Subscription.cs Acquires/releases the gate per subscription event before invoking the query executor.
src/HotChocolate/Core/src/Types/Execution/DependencyInjection/RequestExecutorBuilderExtensions.UseRequest.cs Adds UseConcurrencyGate() and inserts gate into configured pipelines.
src/HotChocolate/Core/src/Types/Execution/DependencyInjection/InternalSchemaServiceCollectionExtensions.cs Injects ExecutionConcurrencyGate into SubscriptionExecutor via DI.
src/HotChocolate/Core/src/Execution.Pipeline/ConcurrencyGateMiddleware.cs Adds execution-level concurrency middleware (skips entirely when disabled/unconfigured).
src/HotChocolate/Core/src/Execution.Pipeline/CommonMiddleware.cs Exposes CommonMiddleware.ConcurrencyGate.
src/HotChocolate/Core/src/Execution.Abstractions/WellKnownRequestMiddleware.cs Adds the well-known key for the new middleware.
src/HotChocolate/Core/src/Execution.Abstractions/Execution/ExecutionConcurrencyGate.cs Implements the semaphore-based execution gate abstraction.
src/HotChocolate/AspNetCore/src/AspNetCore/Extensions/HotChocolateAspNetCoreServiceCollectionExtensions.cs Registers the per-schema ExecutionConcurrencyGate from GraphQLServerOptions.
src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Options/GraphQLServerOptions.cs Renames MaxConcurrentRequestsMaxConcurrentExecutions.
src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/MiddlewareFactory.cs Removes the old HTTP-level concurrency gate middleware.
src/HotChocolate/AspNetCore/src/AspNetCore.Pipeline/Extensions/EndpointRouteBuilderExtensions.cs Removes wiring of the old transport-level gate from endpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md Outdated
Comment thread website/src/docs/fusion/v16/performance-tuning.md Outdated
Comment on lines +256 to +260
if (concurrencyGate is { IsEnabled: true })
{
await concurrencyGate.WaitAsync(requestCancellationToken).ConfigureAwait(false);
gateAcquired = true;
}
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateResponseStream waits on the concurrency gate using requestCancellationToken, but the event loop itself is driven by executionCancellationToken (which can be cancelled independently via the internal execution CTS). If the execution engine is cancelled (e.g. ExecutionState.CancelProcessing()), this wait can keep blocking even though the subscription execution should stop. Use executionCancellationToken (or a linked token of both) for WaitAsync(...) so gate waits abort when the execution is halted.

Copilot uses AI. Check for mistakes.
…ncy-gate

# Conflicts:
#	src/HotChocolate/Fusion/src/Fusion.AspNetCore/DependencyInjection/FusionServerServiceCollectionExtensions.cs
@michaelstaib michaelstaib merged commit 5d704e3 into main Apr 20, 2026
135 checks passed
@michaelstaib michaelstaib deleted the mst/retooled-concurrency-gate branch April 20, 2026 09:45
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (bb9701b) to head (3d90cb9).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@     Coverage Diff      @@
##   main   #9580   +/-   ##
============================
============================

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📚 documentation This issue is about working on our documentation. 🌶️ hot chocolate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants