-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Investigate thread safety of GetReadOnlyTypeInfo and SystemTextJsonOutputFormatter #49849
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
Comments
To clarify, the new method will populate using the default resolver depending on the setting of |
I think fixing this should only prevent a small race where we throw the wrong exception when reflection really is disabled, or something manually set |
|
I saw that PR, but that doesn't explain why we don't make a last-ditch effort to try reflection anyway and just suppress the warnings. Of course, it probably won't work anyway, but it might, and it would be thread safe with the new API. This would require only attempt using |
Suppressing warnings is bad, that is not our first choice (or even second choice) for making things work. The cases where
|
IMO - if we really care about this thread safety issue, then Either that, or we shouldn't need to call |
To explain more here: We 100% don't want to try to fallback to reflection when |
From STJ perspective there's no difference between unconfigured and explicitly setting to
And fall back to the empty resolver that supports no types? That's almost always invalid configuration -- I would say it's preferable to fail fast so that the user can correct it. A sane fallback is what is offered by the new method added in dotnet/runtime#90013, but that must necessarily be marked RUC/RDC.
Agreed. The more I think about it, the more I think that the new |
It came up in API review for MakeReadOnly(bool populateMissingResolver) that the pattern of conditionally setting
JsonSerializerOptions.TypeInfoResolver
before callingMakeReadOnly
is not thread safe and can lead to InvalidOperationExceptions like those in dotnet/runtime#89830 when there's a race.At first blush, GetReadOnlyTypeInfo and the SystemTextJsonOutputFormatter ctor appear to have the same thread safety issue. Of course, if we can guarantee these never run concurrently, there might not be an issue. That could explain why our tests haven't caught this, but I think it's more likely that we just don't have any functional tests where
TypeInfoResolver
would be null by the time it gets to this code.aspnetcore/src/Shared/Json/JsonSerializerExtensions.cs
Lines 19 to 25 in f1cfa8e
aspnetcore/src/Mvc/Mvc.Core/src/Formatters/SystemTextJsonOutputFormatter.cs
Lines 26 to 28 in f1cfa8e
It appears we won't be able to use the newly approved thread-safe
MakeReadOnly(bool populateMissingResolver)
API because we try to set an empty rather than the default reflection-basedTypeInfoResolver
. I'm not sure why that is. Is it an attempt to reduce the need for suppressions when we're doing serialization that is not statically verifiable to be linker safe?I get that it's probably unusual to get a null
TypeInfoResolver
unless reflection is really not supported given whoJsonOptions.DefaultSerializerOptions
gets configured, but it still seems nicer to at least try to fallback to reflection rather than just fail to serialize or deserialize if there's even a small chance that it might work. Wouldn't it effectively just change the exception that's thrown if the reflection fallback fails? Probably to something with a clearer error message?@eerhardt @eiriktsarpalis @captainsafia
The text was updated successfully, but these errors were encountered: