-
Notifications
You must be signed in to change notification settings - Fork 38.1k
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
RequestCondition optimizations #22644
Comments
Team Decision: This was brought up to the team. One comment was that |
Reduce object creation by pre-computing instances that can be re-used, and eliminating collection copying and sorting where not needed. See gh-22644
I've added a new
Further optimizations have also been made to reduce object creation. |
@rstoyanchev I am getting an NPE on line MediaType.java:550 of spring-web-5.2.0.M2.jar (currently line 563 in master) because the cache is apparently returning a null type from MimeTypeUtils.parseMimeType().
and this method doesn't account for null return
I don't see the current code handling this any better than 5.2.0.M2.jar. The MediaType.parseMediaType() method where the NPE is happening should also include the mediaType in the InvalidMimeTypeException that it throws (and it should probably throw that with the mediaType if parseMimeType(mediaType) returns null. I am seeing this NPE today in production (in CAS 6.1.RC4-SNAPSHOT) on requests for a *.woff file (for which I had to turn on trace logging in DispatcherServlet). Yesterday I was seeing it on requests from Google Earth and I don't know what the mime type was or what the request was because I didn't have trace on, but the problem went away after I restarted the CAS (spring boot) application. The fact that restarting fixed the issue for the same Google Earth requests makes me suspect something is wonky with the cache. It looks like it is a LRU cache with max size 64 but what if you process more than 64 mime types? EDIT: I just looked closer at the code and see now that "get" is actually doing more than just pulling from the cache, it is also populating it and not sure how it is returning null, but I am seeing NPE which implied "type" variable is null. |
I think the ConcurrentLruCache in MimeTypeUtils has a bug b/c that is the only way null type could be getting returned. The ConcurrentLruCache.get(key) method does returns in two places and one of them is returning a null. The return in the write lock block looks safe but the return in the read lock block could return null if the internal queue had the same key in it twice but the internal cache map wouldn't necessarily have the value anymore. I think duplicate keys could get in the queue because the key is added to the queue in both the read lock and the write lock under heavy concurrency. Pinging @bclozel since it looks like he wrote ConcurrentLruCache. |
@hdeadman Could you create an issue for that? It seems you've found the underlying problem, which is not related to this issue. |
Done: #23211 |
Awesome, thanks! |
As of spring-projects/spring-framework#22644, Spring Framework caches the "produces" condition when matching for endpoints in the `HandlerMapping` infrastructure. This has been improved in spring-projects/spring-framework#23091 to prevent side-effects in other implementations. Prior to this commit, the Spring Boot actuator infrastructure for `EndpointHandlerMapping` would not clear the cached attribute, presenting the same issue as Spring Framework's infrastructure. This means that a custom arrangement with custom `HandlerMapping` or `ContentTypeResolver` would not work properly and reuse the cached produced conditions for other, unintented, parts of the handler mapping process. This commit clears the cached data and ensures that other handler mapping implementations are free of that side-effect. Fixes gh-20150
Introduce a common cache, e.g.
RequestMappingInfoCache
, that's stored as a request attribute (Spring MVC) or exchange attribute (WebFlux) to avoid repeated re-calculation of request related values required for condition checks.There are already optimizations in WebFlux so request path, "Content-Type", and "Accept" are parsed only once, but even then "Accept" media types are sorted repeatedly + there are other recurring checks like
isPreFlightRequest
. This would allow Spring MVC be more on par with WebFlux in terms of optimal request condition checks.A lot of the base functionality could be in
AbstractRequestCondition
with sub-classes accessingcomputeIfAbsent
type methods from the base class.The text was updated successfully, but these errors were encountered: