-
Notifications
You must be signed in to change notification settings - Fork 302
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
feat: Optimize request validator + make thread safe (backwards compatible) #660
base: main
Are you sure you want to change the base?
Conversation
Relates to twilio#466 Turns out this may just be for correctness, as these algos may not hold onto any unmanaged resources. dotnet/aspnetcore#32871
I'm leaving this PR as a draft for now, as you may want me to remove the benchmark project before pulling it in. |
429f85b
to
813a64b
Compare
Here's an allocation report from VS when running the current unhappy path: And the relevant call tree:
Allocations tab:
We could further improve performance if we don't have to preserve the original casing of the URL, and if we didn't have to check for the URL with and without port. |
Pulling the code from #598 with minor modifications improves the performance and reduces allocations further.
TBD if I'm merging that PR into this one. |
@davidfowl @vcsjones @benmccallum any last suggestions before I turn this into a real PR? |
Much better, thanks again for pushing this along. I've only reviewed on my phone, but it looks good to me and most importantly is thread-safe, so the docs as they were (and I imagine still are) won't lead someone down a path of great misfortune :) |
…to optimize-request-validation
C'mon Twilio folks, this code contribution has been ready to merge on the internal repo and public repo for a long time. The longer you let these things rot, the more conflicts will arise. By not merging this, you're choosing to keep a slower and less memory-efficient version around for no reason. 🔥 🌳 |
Hello @Swimburger! I am looking at this PR from twilio. Can you please update this PR with the latest changes to ensure that the .csproj file has no conflicts? Thanks! |
Conflict resolved |
Review in process |
We even had a review from David Fowler 😄 LGTM! |
All third-party contributors acknowledge that any contributions they provide will be made under the same open-source license that the open-source project is provided under.
ASP.NET Core is pushing performance with every release, and I received feedback that the
RequestValidator
is inefficient.This is not my area of expertise, so there's probably more optimization possible, especially if we can drop older versions of .NET, but I gave it a stab while trying to keep it backwards compatible.
The only breaking change would be that I'm doing some additional input validation which previously would have thrown null reference exceptions instead of argument exceptions. Technically a breaking change, but in reality I don't expect anyone to run into this issue.
Fixes
I created a benchmark project with a copy of the original validation code while improving the existing code.
The benchmark tests for happy path, where the parameters are passed in as a dictionary and the signature matches for the original URL, not needing to perform the validation for the second URL variant.
The unhappy path passes in a name value collection, and doesn't pass on the URL that's passed in, but does match on the variant URL.
The code is more performant because some of the string manipulations that used to be done for every URL is only done once now, and if the first signature matches, the validator doesn't bother checking for the variant URL.
Other than that, there are minor enhancements trying to reduce the amount of objects needed to perform the validation.
Here's the benchmark results for .NET 6:
All the tests continue to pass.
This PR also contains the commits from PR #598 to fix the thread safety issue (fixing #466), and as a result it also improves performance. Thank you @benmccallum.
Checklist
If you have questions, please file a support ticket, or create a GitHub Issue in this repository.