You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{
primaryModel(id: 1) {
idvaluesecondary {
nametertiary {
name
}
}
anotherSecondary {
nametertiary {
name
}
}
}
}
We use Fusion here to first get the primaryModel from exampleService1, then two separate selections of secondaryModel, which get sent as 2 separate requests to exampleService2 at approximately the same time.
What is expected?
We get a result without any errors
What is actually happening?
We encounter an exception on (only) the very first request to ExampleService2. Any subsequent requests will return as expected.
Relevant log output
An item with the same key has already been added. Key:
ExampleService1.TertiaryModel
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Reflection.NullabilityInfoContext.GetNullableContext(MemberInfo memberInfo) at System.Reflection.NullabilityInfoContext.GetNullabilityInfo(MemberInfo memberInfo, Type type, NullableAttributeStateParser parser, Int32& index) at System.Reflection.NullabilityInfoContext.GetNullabilityInfo(MemberInfo memberInfo, Type type, NullableAttributeStateParser parser) at System.Reflection.NullabilityInfoContext.Create(PropertyInfo propertyInfo) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.IsNullableType(PropertyInfo propertyInfo) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildAssignmentExpression(PropertyNode node, Context context) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildSelectionSetExpression(Context context, TypeNode parent) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildTypeSwitchExpression(Context context, TypeContainer parent) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildAssignmentExpression(PropertyNode node, Context context) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildSelectionSetExpression(Context context, TypeNode parent) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildTypeSwitchExpression(Context context, TypeContainer parent) at HotChocolate.Execution.Projections.SelectionExpressionBuilder.BuildExpression[TRoot](ISelection selection) at HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.<>c__2`1.<GetOrCreateExpression>b__2_0(String _, ValueTuple`2 ctx) at HotChocolate.Execution.Processing.Operation.GetOrAddState[TState,TContext](String key, Func`3 createState, TContext context) at HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.GetOrCreateExpression[TValue](ISelection selection) at HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector[TValue](ISelection selection) at GreenDonut.Data.HotChocolateExecutionDataLoaderExtensions.Select[TKey,TValue](IDataLoader`2 dataLoader, ISelection selection) at ExampleService2.Query.GetSecondaryModelByIds(IReadOnlyList`1 ids, ISecondaryModelsDataLoader dataLoader, ISelection selectorBuilder, CancellationToken cancellationToken) in /home/nathan/Projects/HotChocolateConcurrencyBug/HotChocolateConcurrencyBug/ExampleService2/Query.cs:line 17 at HotChocolate.Resolvers.Expressions.ExpressionHelper.AwaitTaskHelper[T](Task`1 task) at HotChocolate.Types.Helpers.FieldMiddlewareCompiler.<>c__DisplayClass9_0.<<CreateResolverMiddleware>b__0>d.MoveNext() --- End of stack trace from previous location --- at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken) at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)
Additional context
This appears to be related to this specific NullabilityInfoContext, which is a static, and can be used across multiple threads:
Product
Hot Chocolate
Version
15.0.3
Link to minimal reproduction
https://github.com/Deukhoofd/HotChocolateConcurrencyBug
Steps to reproduce
Start all three services, send the following request to the gateway at http://localhost:5001/graphql/
We use Fusion here to first get the primaryModel from exampleService1, then two separate selections of secondaryModel, which get sent as 2 separate requests to exampleService2 at approximately the same time.
What is expected?
We get a result without any errors
What is actually happening?
We encounter an exception on (only) the very first request to ExampleService2. Any subsequent requests will return as expected.
Relevant log output
Additional context
This appears to be related to this specific NullabilityInfoContext, which is a static, and can be used across multiple threads:
graphql-platform/src/HotChocolate/Core/src/Execution.Projections/SelectionExpressionBuilder.cs
Line 14 in 5c69f8a
NullabilityInfoContext is however not thread-safe, and should not be used in such a manner (dotnet/runtime#100254)
The text was updated successfully, but these errors were encountered: