-
Notifications
You must be signed in to change notification settings - Fork 470
Significant performance regression in WebHandler #1484
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
Link to #1405 |
It looks like the fundamental problem is that the cache key includes the expanded mapping of the method pointed to which means that we have virtually unlimited cache keys depending on the expanded links we create. I'll try to separate the keys and cached values from that dynamic value so that we still only lookup the static metadata once and combine that with the dynamically to produce URI. |
Moved the affordance metadata caching into SpringAffordanceBuilder and separate the caching of the metadata lookup from the assembly of the affordance. The latter is based on the URI resulting from expanding the request mapping with the given value and thus is likely to produce a lot of different values so that they're rather unsuitable as cache key. That means that we now return fresh Affordance instances for every request which probably causes a tiny hit on performance but still does not need additional metadata lookups. Also, it opens up the door to enrich the affordances with property value providers that would allow us to render affordance fields that refer to a instances property, e.g. to render edit forms.
Would you mind to try the |
Definitely, we can make such a test 👍 |
Is it already published? |
It is, see here. You should be able to consume the artifacts by setting |
It would be hard to test it as the newest changes breaks our unit tests like below:
do you have any best practices how to pass fake It looks like following code won't work at our tests: private Supplier<ConversionService> getConversionService() {
return () -> {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
if (!ServletRequestAttributes.class.isInstance(attributes)) {
return null;
}
ServletContext servletContext = ((ServletRequestAttributes) attributes).getRequest().getServletContext();
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
return context == null || !context.containsBean("mvcConversionService")
? FALLBACK_CONVERSION_SERVICE
: context.getBean("mvcConversionService", ConversionService.class);
};
} as there is no ThreadLocal This condition seems to be broken to me: if (!ServletRequestAttributes.class.isInstance(attributes)) {
return null;
} when attribute is null then it returns null and we can't reach logic:
to use fallback service |
Yet another great catch, @wyhasany! It should affect unit tests only that do not register For reference for others: you nee to use the snapshot repository at |
I've also ported the fix to 1.2.5-SNAPSHOT, if that's easier to try. |
@odrotbohm that looks great, tommorow I'm going to test it |
The another day to test I've made test today it seems that there is no longer regression. Our app works with similiar latency as with spring-hateoas 1.2.2. That's a great job @odrotbohm! 🎊 I think you can close this issue. |
That's great news! I forgot to push the fix for the NPE on master. It should be up and ready for consumption now. I'll do an additional back port to 1.1.x for inclusion in Spring Boot 2.3 then, too. Releases to be shipped tomorrow, for inclusion in Boot releases later this week. |
Looks like 1.1 isn't even affected. |
That was pretty fast! Thanks for awesome support 👍 |
Uh oh!
There was an error while loading. Please reload this page.
Hi! It looks like this PR makes big performance regression for my project. As there is a contention on LRU cache locks. We're creating thousands of links concurrently and threads have to wait for each other. @odrotbohm could you revert that PR or propose non blocking solution?
Here you can see part of profiling my app:

Before that change there is no wall-clock time on that locks.
The reason of that is the
ConcurrentReferenceHashMap
. It doesn't lock onget()
method whileConcurrentLruCache$get
usesReentrantReadWriteLock
.More over (by @mprzeor):
The text was updated successfully, but these errors were encountered: