Fix concurrent request handling for OpenAPI documents#57972
Fix concurrent request handling for OpenAPI documents#57972captainsafia merged 5 commits intodotnet:mainfrom xC0dex:fix/openapi-concurrent-requests
Conversation
|
@dotnet-policy-service agree |
| }; | ||
|
|
||
| // Act | ||
| var results = await Task.WhenAll(requests); |
There was a problem hiding this comment.
I wonder if using Parallel with a bigger number of operations would make this more likely to always run requests that race against each other?
There was a problem hiding this comment.
Thanks. That was an excellent idea. I switched to Parallel.ForAsync and it turned out that the _operationTransformerContextCache field must also be a ConcurrentDictionary.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
| var targetSchema = valueFactory(key); | ||
| _schemas.Add(key, targetSchema); | ||
| return targetSchema; | ||
| return _schemas.GetOrAdd(key, valueFactory(key)); |
There was a problem hiding this comment.
@BrennanConroy shared some feedback here that we can use a different overload of the GetOrAdd method here to avoid another possible race condition:
| return _schemas.GetOrAdd(key, valueFactory(key)); | |
| return _schemas.GetOrAdd(key, valueFactory, key); |
With this pattern, the GetOrAdd method will do a check for the schema key in the dictionary before calling into the factory.
The current overload used will always call the valueFactory even if the key already exists in the dictionary.
In this case, the valueFactory were calling is an invocation into the JsonSchemaMapper. I dunno if it is particularly prone to race issues but it still doesn't hurt to avoid unnecessarily calling into it.
There was a problem hiding this comment.
Thank you for the feedback. One small PR and I already learned a lot!
Unfortunately, the suggested overload does not work because it expects a valueFactory of type Func<TKey, TArg, TValue>. Luckily, there is another overload, so I could do the following:
- return _schemas.GetOrAdd(key, valueFactory(key));
+ return _schemas.GetOrAdd(key, _ => valueFactory(key));There was a problem hiding this comment.
I think this should work, and will avoid needing to allocate a closure:
return _schemas.GetOrAdd(key, valueFactory);* fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly
* Fix JsonUnmappedMemberHandling attribute handling to close #57981 * Fix enum handling for MVC actions to close #57979 * Fix self-referential schema handling to close #58006 * Fix concurrent request handling for OpenAPI documents (#57972) * fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly * Harden self-referencing schema ID check --------- Co-authored-by: Justin Lampe <xC0dex@users.noreply.github.com>
* Fix JsonUnmappedMemberHandling attribute handling to close #57981 * Fix enum handling for MVC actions to close #57979 * Fix self-referential schema handling to close #58006 * Fix concurrent request handling for OpenAPI documents (#57972) * fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly * Harden self-referencing schema ID check --------- Co-authored-by: Justin Lampe <xC0dex@users.noreply.github.com>
… (#58096) * Fix JsonUnmappedMemberHandling attribute handling to close #57981 * Fix enum handling for MVC actions to close #57979 * Fix self-referential schema handling to close #58006 * Fix concurrent request handling for OpenAPI documents (#57972) * fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly * Harden self-referencing schema ID check --------- Co-authored-by: Justin Lampe <xC0dex@users.noreply.github.com>
* fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly
… (#58096) * Fix JsonUnmappedMemberHandling attribute handling to close #57981 * Fix enum handling for MVC actions to close #57979 * Fix self-referential schema handling to close #58006 * Fix concurrent request handling for OpenAPI documents (#57972) * fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly * Harden self-referencing schema ID check --------- Co-authored-by: Justin Lampe <xC0dex@users.noreply.github.com>
* fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly
… (#58096) * Fix JsonUnmappedMemberHandling attribute handling to close #57981 * Fix enum handling for MVC actions to close #57979 * Fix self-referential schema handling to close #58006 * Fix concurrent request handling for OpenAPI documents (#57972) * fix: Allow concurrent requests * test: Update test * test: Use Parallel.ForEachAsync * feat: Use valueFactory overload * feat: Pass valueFactory directly * Harden self-referencing schema ID check --------- Co-authored-by: Justin Lampe <xC0dex@users.noreply.github.com>
Fix: Concurrent request for OpenApi documents
Description
This PR allows concurrent requests for OpenApi documents by switching from a
Dictionaryto aConcurrentDictionary. The fields_schemas,SchemasByReferenceand_operationTransformerContextCachehad to be changed toConcurrentDictionaryto pass the test. Additionally, I updated_referenceIdCounterfor consistency.Fixes #57876