-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix concurrent request handling for OpenAPI documents #57972
Fix concurrent request handling for OpenAPI documents #57972
Conversation
@dotnet-policy-service agree |
}; | ||
|
||
// Act | ||
var results = await Task.WhenAll(requests); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 🚀
var targetSchema = valueFactory(key); | ||
_schemas.Add(key, targetSchema); | ||
return targetSchema; | ||
return _schemas.GetOrAdd(key, valueFactory(key)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: Concurrent request for OpenApi documents
Description
This PR allows concurrent requests for OpenApi documents by switching from a
Dictionary
to aConcurrentDictionary
. The fields_schemas
,SchemasByReference
and_operationTransformerContextCache
had to be changed toConcurrentDictionary
to pass the test. Additionally, I updated_referenceIdCounter
for consistency.Fixes #57876