Skip to content
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

Add some deprecation optimizations #37597

Merged
merged 5 commits into from
Jan 18, 2019

Conversation

jasontedor
Copy link
Member

@jasontedor jasontedor commented Jan 18, 2019

This commit optimizes some of the performance issues from using deprecation logging:

  • we optimize encoding the deprecation value
  • we optimize formatting the deprecation string
  • we optimize away getting the current time (by using cached startup time)

Relates #35754
Relates #37530

This commit optimizes some of the performance issues from using
deprecation logging:
 - we optimize encoding the deprecation value
 - we optimize formatting the deprecation string
 - we optimize away getting the current time (by using cached startup
   time)
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@jasontedor
Copy link
Member Author

This PR together with #37590 reduces the penalty seen in #35754 on my machine from 40x to 10x. The big remaining issue to address is the expensiveness of de-duplicating the warning headers as outlined in #37530.

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jasontedor
Copy link
Member Author

@elasticmachine run gradle build tests 1
@elasticmachine run gradle build tests 2

Copy link
Member

@danielmitterdorfer danielmitterdorfer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this. I left a few comments.

* We want a fast path check to avoid creating the string builder and copying characters if needed. So we walk the string looking
* for either of the characters that we need to escape. If we find a character that needs escaping, we start over and
*/
boolean encodingNeeded = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this variable should be name escapingNeeded as this method is concerned with escaping special characters but not encoding (which is done separately)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed 17646cf.

return String.format(Locale.ROOT, WARNING_FORMAT, escapeAndEncode(s), RFC_7231_DATE_TIME.format(ZonedDateTime.now(GMT)));
return WARNING_PREFIX + " "
+ "\"" + escapeAndEncode(s) + "\"" + " "
+ "\"" + STARTUP_TIME + "\"";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe rewrite as

return WARNING_PREFIX + " \"" + escapeAndEncode(s) + "\" \"" + STARTUP_TIME + "\"";

Or did you think it is too subtle to miss the required spaces in between? Either way, I don't feel too strongly about it.

Copy link
Member Author

@jasontedor jasontedor Jan 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, what is here is clearer IMO, and the compiler will fold the constants anyway (so fold " " and "\"" into " \"", and "\"" and " " and "\"" into "\" \"" so that the number of invocations to StringBuilder#append will be reduced).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me.

return String.format(Locale.ROOT, WARNING_FORMAT, escapeAndEncode(s), RFC_7231_DATE_TIME.format(ZonedDateTime.now(GMT)));
return WARNING_PREFIX + " "
+ "\"" + escapeAndEncode(s) + "\"" + " "
+ "\"" + STARTUP_TIME + "\"";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also find it a bit odd to always use STARTUP_TIME as the value for warn-date but on the other hand I did not find anything in RFC 7234 that forbids doing that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately I want to remove the warn-date from the header. It's not required by the specification (it's optional). However, removing it requires coordinating with Kibana which parses these warning headers for displaying in Console (elastic/kibana#10470). So here I eliminate the performance issue to show the advantages (otherwise, it does show up in profiling output, ~15%).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with that, it just puzzled me in the beginning.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -157,14 +157,13 @@ public void deprecatedAndMaybeLog(final String key, final String msg, final Obje
* arbitrary token; here we use the Elasticsearch version and build hash. The warn text must be quoted. The warn-date is an optional
* quoted field that can be in a variety of specified date formats; here we use RFC 1123 format.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only semi-related to your PR but I think the RFC mentioned in this comment is wrong and it should say "RFC 7231 format" instead of "RFC 1123 format".

@@ -339,7 +338,9 @@ public Void run() {
* @return a warning value formatted according to RFC 7234
*/
public static String formatWarning(final String s) {
return String.format(Locale.ROOT, WARNING_FORMAT, escapeAndEncode(s), RFC_7231_DATE_TIME.format(ZonedDateTime.now(GMT)));
return WARNING_PREFIX + " "
+ "\"" + escapeAndEncode(s) + "\"" + " "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to your PR: While I am not aware that any RFC specifies a maximum field length for HTTP headers there are practical limits and I wonder whether we should enforce one (in a follow-up) as deprecation messages might be long?

Copy link
Member

@danielmitterdorfer danielmitterdorfer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jasontedor
Copy link
Member Author

@elasticmachine run gradle build tests 2

1 similar comment
@jasontedor
Copy link
Member Author

@elasticmachine run gradle build tests 2

@jasontedor
Copy link
Member Author

@elasticmachine run gradle builds tests 2

@jasontedor
Copy link
Member Author

@elasticmachine run gradle build tests 2

1 similar comment
@jasontedor
Copy link
Member Author

@elasticmachine run gradle build tests 2

@jasontedor jasontedor merged commit adae233 into elastic:master Jan 18, 2019
@jasontedor jasontedor deleted the some-deprecation-optimizations branch January 18, 2019 21:45
jasontedor added a commit that referenced this pull request Jan 18, 2019
This commit optimizes some of the performance issues from using
deprecation logging:
 - we optimize encoding the deprecation value
 - we optimize formatting the deprecation string
 - we optimize away getting the current time (by using cached startup
   time)
jasontedor added a commit to jasontedor/elasticsearch that referenced this pull request Jan 21, 2019
* elastic/master: (104 commits)
  Permission for restricted indices (elastic#37577)
  Remove Watcher Account "unsecure" settings (elastic#36736)
  Add cache cleaning task for ML snapshot (elastic#37505)
  Update jdk used by the docker builds (elastic#37621)
  Remove an unused constant in PutMappingRequest.
  Update get users to allow unknown fields (elastic#37593)
  Do not add index event listener if CCR disabled (elastic#37432)
  Add local session timeouts to leader node (elastic#37438)
  Add some deprecation optimizations (elastic#37597)
  refactor inner geogrid classes to own class files (elastic#37596)
  Remove obsolete deprecation checks (elastic#37510)
  ML: Add support for single bucket aggs in Datafeeds (elastic#37544)
  ML: creating ML State write alias and pointing writes there (elastic#37483)
  Deprecate types in the put mapping API. (elastic#37280)
  [ILM] Add unfollow action (elastic#36970)
  Packaging: Update marker used to allow ELASTIC_PASSWORD (elastic#37243)
  Fix setting openldap realm ssl config
  Document the need for JAVA11_HOME (elastic#37589)
  SQL: fix object extraction from sources (elastic#37502)
  Nit in settings.gradle for Eclipse
  ...
@@ -384,7 +409,7 @@ static String escapeBackslashesAndQuotes(final String s) {
for (int i = 0x80; i <= 0xFF; i++) {
doesNotNeedEncoding.set(i);
}
assert !doesNotNeedEncoding.get('%');
assert doesNotNeedEncoding.get('%') == false : doesNotNeedEncoding;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants