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 method to check if object is generically writeable in stream #54936

Merged
merged 3 commits into from
Apr 21, 2020

Conversation

rjernst
Copy link
Member

@rjernst rjernst commented Apr 8, 2020

When calling scripts in metric aggregation, the returned metric state is
passed along to the coordinating node to do the final reduce. However,
it is possible the object could contain nested state which is unknown to
StreamOutput/StreamInput. This would then result in the node crashing as
exceptions are not expected in the middle of serialization.

This commit adds a method to StreamOutput that can determine if an
object is writeable by the stream. It uses the same logic
writeGenericValue, special casing each of the supported collection types
to recursively determine if each contained value is itself writeable.

relates #54708

When calling scripts in metric aggregation, the returned metric state is
passed along to the coordinating node to do the final reduce. However,
it is possible the object could contain nested state which is unknown to
StreamOutput/StreamInput. This would then result in the node crashing as
exceptions are not expected in the middle of serialization.

This commit adds a method to StreamOutput that can determine if an
object is writeable by the stream. It uses the same logic
writeGenericValue, special casing each of the supported collection types
to recursively determine if each contained value is itself writeable.

relates elastic#54708
@rjernst rjernst added >bug :Analytics/Aggregations Aggregations :Core/Infra/Core Core issues without another label :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache v8.0.0 v7.8.0 v7.7.1 labels Apr 8, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-analytics-geo (:Analytics/Aggregations)

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (:Core/Infra/Scripting)

@rjernst
Copy link
Member Author

rjernst commented Apr 8, 2020

@original-brownbear I can add some tests for the new method, but I wanted to first get initial thoughts on the approach.

Copy link
Member

@original-brownbear original-brownbear left a comment

Choose a reason for hiding this comment

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

I think in general the approach is fine, one question on the possible scope of using this.

@@ -90,6 +91,7 @@ public InternalAggregation buildAggregation(long owningBucketOrdinal) {
} else {
aggregation = aggState;
}
StreamOutput.checkWriteable(aggregation);
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we could/should combine this with org.elasticsearch.common.util.CollectionUtils#ensureNoSelfReferences(java.lang.Object, java.lang.String) somehow? It seems like technically we would want to use this in all the spots that we currently also use that method to validate script returns (maybe I'm missing some detail and we wouldn't need to do this kind of validation in other script return spots and only need the no-self-references there for some reason?). That way we'd save iterating through the object to validate twice?

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'm not sure we need both in all cases. ensureNoSelfReferences guarantees we can do any operation on the object in question (not resulting in an infinite loop). Checking if the object is writeable is only needed when we plan to write the object to transfer to another node. For example, with scripted metric aggs, we don't every write the node local results from init or map scripts, only the output of combine here that would be transferred to the coordinating node for the final reduce.

Copy link
Member

Choose a reason for hiding this comment

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

Ok makes sense then :) => I think the approach is fine.

@rjernst
Copy link
Member Author

rjernst commented Apr 20, 2020

@original-brownbear I've added tests, so this is ready for a full review.

Copy link
Member

@original-brownbear original-brownbear left a comment

Choose a reason for hiding this comment

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

LGTM thanks Ryan!

@rjernst rjernst merged commit 62b4964 into elastic:master Apr 21, 2020
@rjernst rjernst deleted the stream_iswriteable branch April 21, 2020 23:31
rjernst added a commit to rjernst/elasticsearch that referenced this pull request Apr 21, 2020
…stic#54936)

When calling scripts in metric aggregation, the returned metric state is
passed along to the coordinating node to do the final reduce. However,
it is possible the object could contain nested state which is unknown to
StreamOutput/StreamInput. This would then result in the node crashing as
exceptions are not expected in the middle of serialization.

This commit adds a method to StreamOutput that can determine if an
object is writeable by the stream. It uses the same logic
writeGenericValue, special casing each of the supported collection types
to recursively determine if each contained value is itself writeable.

relates elastic#54708
rjernst added a commit that referenced this pull request Apr 28, 2020
) (#55561)

When calling scripts in metric aggregation, the returned metric state is
passed along to the coordinating node to do the final reduce. However,
it is possible the object could contain nested state which is unknown to
StreamOutput/StreamInput. This would then result in the node crashing as
exceptions are not expected in the middle of serialization.

This commit adds a method to StreamOutput that can determine if an
object is writeable by the stream. It uses the same logic
writeGenericValue, special casing each of the supported collection types
to recursively determine if each contained value is itself writeable.

relates #54708
@williamrandolph williamrandolph removed :Analytics/Aggregations Aggregations :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache labels May 29, 2020
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.

5 participants