-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Closed
Labels
area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
It appears that the current implementation of OpenApiSchemaStore
does not handle concurrent requests as expected. While I thought that I resolved the issue in #57972, the problem persists under certain conditions.
Observed Behavior:
When running the service in a Linux-based Docker container, the issue occurs almost every time on the first request.
However, when I test it locally on my Windows machine, I am unable to reproduce this issue. That's why I thought it's fixed.
Expected Behavior
The OpenApiSchemaStore
should handle concurrent requests without issues.
Steps To Reproduce
- Use the
Scalar.AspNetCore
package. - Start the API in a Docker container (In my case Linux-based).
- Trigger concurrent requests by opening
/scalar/v1
in the browser (Scalar initiates two parallel requests on startup, reported here).
Exceptions (if any)
Relevant log output:
fail: Microsoft.AspNetCore.Server.Kestrel[13]
api-1 | Connection id "0HN805CSINAPJ", Request id "0HN805CSINAPJ:00000003": An unhandled exception was thrown by the application.
api-1 | System.ArgumentException: An item with the same key has already been added. Key: OpenApiSchemaKey { Type = Scalar.AspNetCore.Playground.Books.Book[], ParameterInfo = }
api-1 | at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
api-1 | at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiSchemaStore.GetOrAdd(OpenApiSchemaKey key, Func`2 valueFactory)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiSchemaService.GetOrCreateSchemaAsync(Type type, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, ApiParameterDescription parameterDescription, Boolean captureSchemaByRef, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetResponseAsync(ApiDescription apiDescription, Int32 statusCode, ApiResponseType apiResponseType, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetResponsesAsync(ApiDescription description, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOperationAsync(ApiDescription description, HashSet`1 capturedTags, IServiceProvider scopedServiceProvider, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOperationsAsync(IGrouping`2 descriptions, HashSet`1 capturedTags, IServiceProvider scopedServiceProvider, IOpenApiOperationTransformer[] operationTransformers, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiPathsAsync(HashSet`1 capturedTags, IServiceProvider scopedServiceProvider, IOpenApiOperationTransformer[] operationTransformers, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiDocumentAsync(IServiceProvider scopedServiceProvider, CancellationToken cancellationToken)
api-1 | at Microsoft.AspNetCore.Builder.OpenApiEndpointRouteBuilderExtensions.<>c__DisplayClass0_0.<<MapOpenApi>b__0>d.MoveNext()
api-1 | --- End of stack trace from previous location ---
api-1 | at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F56B68D2B55B5B7B373BA2E4796D897848BC0F04A969B1AF6260183E8B9E0BAF2__GeneratedRouteBuilderExtensionsCore.<>c__DisplayClass2_0.<<MapGet0>g__RequestHandler|5>d.MoveNext()
api-1 | --- End of stack trace from previous location ---
api-1 | at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
api-1 | at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
api-1 | at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
api-1 | at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
.NET Version
9.0.100-rc.2.24474.11
Microsoft.AspNetCore.OpenApi
version 9.0.0-rc.2.24474.3
Anything else?
Happy to help with resolving this issue!
Metadata
Metadata
Assignees
Labels
area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi