-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
Improve warning value extraction performance in Response #50208
Improve warning value extraction performance in Response #50208
Conversation
…sponse to improve performance
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 for picking this up @darrenfoong!
The new code in
getWarnings()
also assumes that all warnings follow theWARNING_HEADER_PATTERN
format.
This assumption is not valid for the REST client. The problem here is the REST client could be connecting through an HTTP proxy, which might add its own warning headers. There is no guarantee these warnings headers can be parsed with this code. This is why the original implementation checked if the warning header matched the pattern, and extracted the warning, and otherwise copied the entire content of the header value.
All is not lost here, we only need to avoid blowing up if the warning header is not in the format that we expect it in. We can do this without a regular expression, and without over-complicating the code. Can you take a stab at that?
Pinging @elastic/es-core-features (:Core/Features/Java Low Level REST Client) |
I added Therefore I added a new regex (!) to match the date and remove it. Fortunately this regex can be optimized to fail fast and prevent backtracking. A quick benchmark showed that this is still 10x faster than the original approach using |
Sorry for the delay here, holidays and all that. I'll review this in the next day. |
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.
The production code looks good, I left a few minor comments. It looks like we're lacking test coverage here. Can you add some basic tests to check the extraction logic for:
- a valid warning with a date
- a valid warning without a date
- a warning that is not an Elasticsearch-formatted warning (e.g., added by a proxy)
client/rest/src/main/java/org/elasticsearch/client/Response.java
Outdated
Show resolved
Hide resolved
…RNING_HEADER_DATE_PATTERN
… a sample warning from RFC 7234
I've addressed the comments, and also updated
|
@elasticmachine update branch |
@elasticmachine test this please |
1 similar comment
@elasticmachine test this please |
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.
This commit improves the performance of warning value extraction in the low-level REST client, and is similar to the approach taken in #24114. There are some differences since the low-level REST client might be connected to Elasticsearch through a proxy that injects its own warnings.
This commit improves the performance of warning value extraction in the low-level REST client, and is similar to the approach taken in #24114. There are some differences since the low-level REST client might be connected to Elasticsearch through a proxy that injects its own warnings.
Thanks a lot @darrenfoong! |
Thanks @jasontedor for the guidance! Is there a reason why this will not be included in 6.8.7? I'm using 6.x, although I can still do without this patch by tweaking the |
This commit improves the performance of warning value extraction in the low-level REST client, and is similar to the approach taken in be connected to Elasticsearch through a proxy that injects its own warnings.
I backported this to 6.8 too. |
Thanks! |
This commit improves the performance of warning value extraction in the low-level REST client, and is similar to the approach taken in elastic#24114. There are some differences since the low-level REST client might be connected to Elasticsearch through a proxy that injects its own warnings.
Hi Jason, Spring Boot 2.2.6 upgraded to 6.8.7 and this fix is causing issues:
|
It seems that you're running against Elasticsearch 7.6.1, which is returning a warning whose hash is longer than the seven characters expected by WARNING_HEADER_PATTERN. |
This PR is similar to #24114 by @jasontedor.
Warnings are returned in REST responses (
Response
) when a deprecated feature is used. A regular expression inResponse
(identical to that inDeprecationLogger
) is used to capture the warning. As mentioned in #24114, this regular expression suffers from excessive backtracking, and caused aStackOverflowError
in my High Level REST Client, which was using the-Xss
JVM option that reduced the size of the stack.Even if a client were to use a normal stack size, the optimization that was used in
DeprecationLogger
could mean performance improvements when handling REST responses (albeit only when there are warnings). A quick benchmark showed that the substring method (around 10 μs) is 50x faster than the regex method (around 500 μs).Some notes:
Response
andDeprecationLogger
. However, I am not familiar enough with the Elasticsearch code base to determine where is a good place to put this utility class.getWarnings()
also assumes that all warnings follow theWARNING_HEADER_PATTERN
format.