Skip to content

Move GetRootServiceProvider to abstractions#9067

Merged
tobias-tengler merged 1 commit intomainfrom
tte/some-api-fixes
Jan 27, 2026
Merged

Move GetRootServiceProvider to abstractions#9067
tobias-tengler merged 1 commit intomainfrom
tte/some-api-fixes

Conversation

@tobias-tengler
Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings January 27, 2026 09:55
@tobias-tengler tobias-tengler merged commit 50ec4d1 into main Jan 27, 2026
121 of 122 checks passed
@tobias-tengler tobias-tengler deleted the tte/some-api-fixes branch January 27, 2026 10:07
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 27, 2026

Codecov Report

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

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

☔ 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.

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 pull request refactors the GetRootServiceProvider extension methods by moving them from concrete implementation files to the abstractions layer, centralizing them in a single location for better maintainability and reusability.

Changes:

  • Moved GetRootServiceProvider extension methods from execution and fusion implementation files to a new ExecutionServiceProviderExtensions class in the abstractions layer
  • Changed parameter type from concrete Schema class to ISchemaDefinition interface for better abstraction
  • Added Microsoft.Extensions.DependencyInjection.Abstractions package reference to support the new extension methods
  • Added BuildRequestExecutorAsync helper method for IFusionGatewayBuilder

Reviewed changes

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

Show a summary per file
File Description
src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/HotChocolateFusionServiceCollectionExtensions.cs Removed duplicate GetRootServiceProvider extension method
src/HotChocolate/Core/src/Execution/DependencyInjection/InternalSchemaServiceCollectionExtensions.cs Removed duplicate GetRootServiceProvider extension methods (both Schema and IServiceProvider overloads)
src/HotChocolate/Core/src/Execution.Abstractions/HotChocolate.Execution.Abstractions.csproj Added Microsoft.Extensions.DependencyInjection.Abstractions package reference
src/HotChocolate/Core/src/Execution.Abstractions/Execution/Extensions/ExecutionServiceProviderExtensions.cs New centralized location for GetRootServiceProvider extension methods with ISchemaDefinition parameter
src/HotChocolate/Fusion-vnext/src/Fusion.Execution/DependencyInjection/CoreFusionGatewayBuilderExtensions.Services.cs Added BuildRequestExecutorAsync helper method and HotChocolate.Execution using statement

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

Comment on lines +31 to +32
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This method is a duplicate of the existing BuildRequestExecutorAsync extension method found in src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorServiceProviderExtensions.cs (lines 109-117). Both IFusionGatewayBuilder and IRequestExecutorBuilder have identical structure (Name and Services properties), so this duplication could be avoided by either: 1) extracting a common interface, 2) creating a shared helper method, or 3) using a generic extension method that works with any type that has a Services property of type IServiceCollection.

Suggested change
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
.BuildRequestExecutorAsync(schemaName, cancellationToken);

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +27
public static ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default) =>
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This method is missing XML documentation comments. Based on the existing pattern in the codebase (see RequestExecutorServiceProviderExtensions.cs lines 93-109), this method should include XML documentation describing its purpose, parameters, and return value.

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +32
public static ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default) =>
builder
.Services
.BuildServiceProvider()
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Calling BuildServiceProvider() creates a new service provider instance that is not disposed. This can lead to resource leaks, especially if the service provider contains disposable services. The existing implementation in RequestExecutorServiceProviderExtensions.cs has the same issue, but adding another instance of this pattern compounds the problem. Consider documenting this limitation or using a using statement to ensure proper disposal.

Suggested change
public static ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default) =>
builder
.Services
.BuildServiceProvider()
.GetRequiredService<IRequestExecutorProvider>()
.GetExecutorAsync(schemaName, cancellationToken);
public static async ValueTask<IRequestExecutor> BuildRequestExecutorAsync(
this IFusionGatewayBuilder builder,
string? schemaName = null,
CancellationToken cancellationToken = default)
{
using var serviceProvider = builder.Services.BuildServiceProvider();
var executorProvider = serviceProvider.GetRequiredService<IRequestExecutorProvider>();
return await executorProvider
.GetExecutorAsync(schemaName, cancellationToken)
.ConfigureAwait(false);
}

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Fusion Gateway Performance Results

Simple Composite Query

Constant Load (50 VUs)

Requests/sec Error Rate
5844.23 req/s 0.00%
📊 Response Time Metrics
Min Med Max Avg P90 P95
0.80ms 7.18ms 165.45ms 8.40ms 12.90ms 17.98ms

Ramping Load (0→50→500→50 VUs)

Requests/sec Error Rate
4543.44 req/s 0.00%
📊 Response Time Metrics
Min Med Max Avg P90 P95
0.82ms 38.58ms 261.19ms 48.92ms 110.28ms 127.74ms

Executed Query

fragment User on User {
  id
  username
  name
}

fragment Review on Review {
  id
  body
}

fragment Product on Product {
  inStock
  name
  price
  shippingEstimate
  upc
  weight
}

query TestQuery {
  topProducts(first: 5) {
    ...Product
    reviews {
      ...Review
      author {
        ...User
      }
    }
  }
}

Deep Recursion Query

Constant Load (50 VUs)

Requests/sec Error Rate
269.31 req/s 0.00%
📊 Response Time Metrics
Min Med Max Avg P90 P95
12.88ms 175.20ms 564.34ms 179.99ms 225.22ms 247.55ms

Ramping Load (0→50→500→50 VUs)

Requests/sec Error Rate
304.09 req/s 0.00%
📊 Response Time Metrics
Min Med Max Avg P90 P95
3.06ms 661.16ms 1789.46ms 693.59ms 1399.95ms 1528.65ms

Executed Query

fragment User on User {
  id
  username
  name
}

fragment Review on Review {
  id
  body
}

fragment Product on Product {
  inStock
  name
  price
  shippingEstimate
  upc
  weight
}

query TestQuery {
  users {
    ...User
    reviews {
      ...Review
      product {
        ...Product
        reviews {
          ...Review
          author {
            ...User
            reviews {
              ...Review
              product {
                ...Product
              }
            }
          }
        }
      }
    }
  }
  topProducts(first: 5) {
    ...Product
    reviews {
      ...Review
      author {
        ...User
        reviews {
          ...Review
          product {
            ...Product
          }
        }
      }
    }
  }
}

Variable Batching Throughput

Constant Load (50 VUs)

Requests/sec Error Rate
23686.50 req/s 0.00%
📊 Response Time Metrics
Min Med Max Avg P90 P95
0.09ms 1.70ms 39.54ms 2.06ms 3.92ms 4.79ms

Ramping Load (0→50→500→50 VUs)

Requests/sec Error Rate
19093.58 req/s 0.00%
📊 Response Time Metrics
Min Med Max Avg P90 P95
0.09ms 8.95ms 118.38ms 11.06ms 22.96ms 27.66ms

Executed Query

query TestQuery_8f7a46ce_2(
  $__fusion_1_upc: ID!
  $__fusion_2_price: Long!
  $__fusion_2_weight: Long!
) {
  productByUpc(upc: $__fusion_1_upc) {
    inStock
    shippingEstimate(weight: $__fusion_2_weight, price: $__fusion_2_price)
  }
}

Variables (5 sets batched in single request)

[
  { "__fusion_1_upc": "1", "__fusion_2_price": 899, "__fusion_2_weight": 100 },
  { "__fusion_1_upc": "2", "__fusion_2_price": 1299, "__fusion_2_weight": 1000 },
  { "__fusion_1_upc": "3", "__fusion_2_price": 15, "__fusion_2_weight": 20 },
  { "__fusion_1_upc": "4", "__fusion_2_price": 499, "__fusion_2_weight": 100 },
  { "__fusion_1_upc": "5", "__fusion_2_price": 1299, "__fusion_2_weight": 1000 }
]

No baseline data available for comparison.


Run 21392629778 • Commit bf56797 • Tue, 27 Jan 2026 10:14:53 GMT

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants