Add XContent chunking to SearchResponse#94736
Conversation
|
Pinging @elastic/es-search (Team:Search) |
| return Iterators.concat( | ||
| ChunkedToXContentHelper.startObject(), | ||
| Iterators.single((b, p) -> b.field("took", tookInMillis).startArray(Fields.RESPONSES)), | ||
| Iterators.flatMap(Arrays.stream(items).iterator(), item -> item.toXContentChunked(params)), |
There was a problem hiding this comment.
There might be a nicer way to include an array of objects which themselves implement ChunkedToXContent but I couldn't find one
There was a problem hiding this comment.
This is fine IMO but there's no need for the intermediate stream:
| Iterators.flatMap(Arrays.stream(items).iterator(), item -> item.toXContentChunked(params)), | |
| Iterators.flatMap(Iterators.forArray(items), item -> item.toXContentChunked(params)), |
| return Iterators.concat( | ||
| Iterators.single((ToXContent) SearchResponse.this::headerToXContent), | ||
| Iterators.single(clusters), | ||
| Iterators.flatMap(Iterators.single(internalResponse), r -> r.toXContentChunked(params)) |
There was a problem hiding this comment.
Similarly I feel there ought to be a nicer way of doing this but I couldn't find one...
There was a problem hiding this comment.
I think you're looking for this:
| Iterators.flatMap(Iterators.single(internalResponse), r -> r.toXContentChunked(params)) | |
| internalResponse.toXContentChunked(params) |
|
This is an interesting test failure. There's a composite aggs test that checks that we get a specific exception if keys are being formatted in a lossy fashion, and this exception is thrown during xcontent parsing. But with chunking we don't seem to catch exceptions thrown by parsing code, and so we get a 'failure encoding chunk' message instead. Is this something we've already encountered elsewhere or do I need to add some extra error handling here? |
|
For a standard RestToXContentListener errors are handled by the |
|
This is a drawback of the chunked encoding: we have to be sure that the serialization will succeed before we start. Once we start sending chunks to the client we can't change our minds about the response code and return an error. |
|
It looks as though we have quite a few places (mainly in aggs) that have this late checking. I can work through the tests and try and fix them, but it blocks making any changes here for the moment, unfortunately. |
|
I've opened #94760 to discuss moving key format checks earlier in the aggregation process. |
...es/lang-mustache/src/main/java/org/elasticsearch/script/mustache/SearchTemplateResponse.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/search/MultiSearchResponse.java
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/search/SearchResponse.java
Outdated
Show resolved
Hide resolved
| return Iterators.concat( | ||
| Iterators.flatMap(Iterators.single(hits), r -> r.toXContentChunked(params)), | ||
| Iterators.single((ToXContent) (b, p) -> { | ||
| if (aggregations != null) { |
There was a problem hiding this comment.
I see why moving these checks inside the Iterator helps enumerating everything in one concat call, but this way we create iterators the we already know will be a noop. Don't know if its worth pulling these out. maybe readability suffers then, leave it up to you to decide.
There was a problem hiding this comment.
Yeah I went back and forth on this a bit, but I think this is the most readable way of doing it, and creating no-op iterators is pretty low cost.
| @Override | ||
| public XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException { | ||
| searchHits.toXContent(builder, params); | ||
| ChunkedToXContent.wrapAsToXContent(searchHits).toXContent(builder, params); |
There was a problem hiding this comment.
Question out of curiosity: I thought the final goal would be to convert everything in search to a "chunked" xcontent variant. This looks a bit like for aggregations we aren't? Is this reading correct, if so is this future work or does that mean aggregations remain larger "chunks"
There was a problem hiding this comment.
Yes, the plan is to do this bit-by-bit. So we start off by chunking search into search hits and aggregations, and we can then look at breaking these chunks into smaller ones in the future.
| if (searchResponse != null) { | ||
| builder.field("response"); | ||
| searchResponse.toXContent(builder, params); | ||
| ChunkedToXContent.wrapAsToXContent(searchResponse).toXContent(builder, params); |
There was a problem hiding this comment.
Just want to verify if AsyncSearchResponse will be changed over to ChunkedToXContentObject as well at some point and if we already have plans for that?
There was a problem hiding this comment.
I've created #95661 to keep track of these.
|
@romseygeek thanks, change looks great in general to me, I left a couple of questions |
|
@romseygeek fyi I'm out for a couple of days, the questions I left aren't strong asks for changes so shouldn't block you from continuing this and for other to approve and get this PR merged. |
|
@elasticmachine run elasticsearch-ci/part-1 |
1 similar comment
|
@elasticmachine run elasticsearch-ci/part-1 |
|
@elasticmachine run elasticsearch-ci/part-2 |
|
@elasticmachine update branch |
|
This is ready for another round of reviews |
|
@elasticmachine update branch |
cbuescher
left a comment
There was a problem hiding this comment.
Thanks for the update, I left one question regarding how much extra work we expect for the xContent validation happening for the search hits in the FetchPhase.
| SearchHits hits = null; | ||
| try { | ||
| hits = buildSearchHits(context, profiler); | ||
| try (XContentBuilder xContentValidator = new XContentBuilder(XContentType.JSON.xContent(), OutputStream.nullOutputStream())) { |
There was a problem hiding this comment.
Question for better understanding: this validator builder is used to completely serialize the search hits once on the node before sending them across the wire and then thrown away? Is there an understanding of the extra work this involves? I see why validation is necessary for chunking but I want to make sure I understand the tradeoffs here.
There was a problem hiding this comment.
Actually I think #95673 means that I can remove this bit, good catch!
This commit adds xcontent chunking to SearchResponse and MultiSearchResponse
by making SearchHits implement ChunkedToXContent.
Relates to #89838