Skip to content

Commit 5d784d6

Browse files
Chunked Encoding for NodeStatsResponse (#90097)
Turn this into a chunked response to some degree. Only chunks per node for now, since deeper chunking needs larger changes downstream that don't fit in well with the current API.
1 parent bfda66a commit 5d784d6

File tree

5 files changed

+88
-47
lines changed

5 files changed

+88
-47
lines changed

server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodeStats.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,52 +40,52 @@
4040
*/
4141
public class NodeStats extends BaseNodeResponse implements ToXContentFragment {
4242

43-
private long timestamp;
43+
private final long timestamp;
4444

4545
@Nullable
4646
private NodeIndicesStats indices;
4747

4848
@Nullable
49-
private OsStats os;
49+
private final OsStats os;
5050

5151
@Nullable
52-
private ProcessStats process;
52+
private final ProcessStats process;
5353

5454
@Nullable
55-
private JvmStats jvm;
55+
private final JvmStats jvm;
5656

5757
@Nullable
58-
private ThreadPoolStats threadPool;
58+
private final ThreadPoolStats threadPool;
5959

6060
@Nullable
61-
private FsInfo fs;
61+
private final FsInfo fs;
6262

6363
@Nullable
64-
private TransportStats transport;
64+
private final TransportStats transport;
6565

6666
@Nullable
67-
private HttpStats http;
67+
private final HttpStats http;
6868

6969
@Nullable
70-
private AllCircuitBreakerStats breaker;
70+
private final AllCircuitBreakerStats breaker;
7171

7272
@Nullable
73-
private ScriptStats scriptStats;
73+
private final ScriptStats scriptStats;
7474

7575
@Nullable
76-
private ScriptCacheStats scriptCacheStats;
76+
private final ScriptCacheStats scriptCacheStats;
7777

7878
@Nullable
79-
private DiscoveryStats discoveryStats;
79+
private final DiscoveryStats discoveryStats;
8080

8181
@Nullable
82-
private IngestStats ingestStats;
82+
private final IngestStats ingestStats;
8383

8484
@Nullable
85-
private AdaptiveSelectionStats adaptiveSelectionStats;
85+
private final AdaptiveSelectionStats adaptiveSelectionStats;
8686

8787
@Nullable
88-
private IndexingPressureStats indexingPressureStats;
88+
private final IndexingPressureStats indexingPressureStats;
8989

9090
public NodeStats(StreamInput in) throws IOException {
9191
super(in);

server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
package org.elasticsearch.action.admin.cluster.node.stats;
1010

1111
import org.elasticsearch.action.FailedNodeException;
12-
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
12+
import org.elasticsearch.action.support.nodes.BaseNodesXContentResponse;
1313
import org.elasticsearch.cluster.ClusterName;
1414
import org.elasticsearch.common.Strings;
15+
import org.elasticsearch.common.collect.Iterators;
1516
import org.elasticsearch.common.io.stream.StreamInput;
1617
import org.elasticsearch.common.io.stream.StreamOutput;
17-
import org.elasticsearch.xcontent.ToXContentFragment;
18-
import org.elasticsearch.xcontent.XContentBuilder;
19-
import org.elasticsearch.xcontent.XContentFactory;
18+
import org.elasticsearch.xcontent.ToXContent;
2019

2120
import java.io.IOException;
21+
import java.util.Iterator;
2222
import java.util.List;
2323

24-
public class NodesStatsResponse extends BaseNodesResponse<NodeStats> implements ToXContentFragment {
24+
public class NodesStatsResponse extends BaseNodesXContentResponse<NodeStats> {
2525

2626
public NodesStatsResponse(StreamInput in) throws IOException {
2727
super(in);
@@ -42,30 +42,21 @@ protected void writeNodesTo(StreamOutput out, List<NodeStats> nodes) throws IOEx
4242
}
4343

4444
@Override
45-
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
46-
builder.startObject("nodes");
47-
for (NodeStats nodeStats : getNodes()) {
48-
builder.startObject(nodeStats.getNode().getId());
49-
builder.field("timestamp", nodeStats.getTimestamp());
50-
nodeStats.toXContent(builder, params);
51-
52-
builder.endObject();
53-
}
54-
builder.endObject();
55-
56-
return builder;
45+
protected Iterator<? extends ToXContent> xContentChunks() {
46+
return Iterators.concat(
47+
Iterators.single((b, p) -> b.startObject("nodes")),
48+
getNodes().stream().map(nodeStats -> (ToXContent) (b, p) -> {
49+
b.startObject(nodeStats.getNode().getId());
50+
b.field("timestamp", nodeStats.getTimestamp());
51+
nodeStats.toXContent(b, p);
52+
return b.endObject();
53+
}).iterator(),
54+
Iterators.single((b, p) -> b.endObject())
55+
);
5756
}
5857

5958
@Override
6059
public String toString() {
61-
try {
62-
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
63-
builder.startObject();
64-
toXContent(builder, EMPTY_PARAMS);
65-
builder.endObject();
66-
return Strings.toString(builder);
67-
} catch (IOException e) {
68-
return "{ \"error\" : \"" + e.getMessage() + "\"}";
69-
}
60+
return Strings.toString(this, true, true);
7061
}
7162
}

server/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesResponse.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
public abstract class BaseNodesResponse<TNodeResponse extends BaseNodeResponse> extends ActionResponse {
2424

25-
private ClusterName clusterName;
26-
private List<FailedNodeException> failures;
27-
private List<TNodeResponse> nodes;
25+
private final ClusterName clusterName;
26+
private final List<FailedNodeException> failures;
27+
private final List<TNodeResponse> nodes;
2828
private Map<String, TNodeResponse> nodesMap;
2929

3030
protected BaseNodesResponse(StreamInput in) throws IOException {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.action.support.nodes;
10+
11+
import org.elasticsearch.action.FailedNodeException;
12+
import org.elasticsearch.cluster.ClusterName;
13+
import org.elasticsearch.common.collect.Iterators;
14+
import org.elasticsearch.common.io.stream.StreamInput;
15+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
16+
import org.elasticsearch.rest.action.RestActions;
17+
import org.elasticsearch.xcontent.ToXContent;
18+
19+
import java.io.IOException;
20+
import java.util.Iterator;
21+
import java.util.List;
22+
23+
public abstract class BaseNodesXContentResponse<TNodeResponse extends BaseNodeResponse> extends BaseNodesResponse<TNodeResponse>
24+
implements
25+
ChunkedToXContent {
26+
27+
protected BaseNodesXContentResponse(ClusterName clusterName, List<TNodeResponse> nodes, List<FailedNodeException> failures) {
28+
super(clusterName, nodes, failures);
29+
}
30+
31+
protected BaseNodesXContentResponse(StreamInput in) throws IOException {
32+
super(in);
33+
}
34+
35+
@Override
36+
public final Iterator<? extends ToXContent> toXContentChunked() {
37+
return Iterators.concat(Iterators.single((b, p) -> {
38+
b.startObject();
39+
RestActions.buildNodesHeader(b, p, this);
40+
return b.field("cluster_name", getClusterName().value());
41+
}), xContentChunks(), Iterators.single((ToXContent) (b, p) -> b.endObject()));
42+
}
43+
44+
@Override
45+
public boolean isFragment() {
46+
return false;
47+
}
48+
49+
protected abstract Iterator<? extends ToXContent> xContentChunks();
50+
}

server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesStatsAction.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import org.elasticsearch.core.RestApiVersion;
1818
import org.elasticsearch.rest.BaseRestHandler;
1919
import org.elasticsearch.rest.RestRequest;
20-
import org.elasticsearch.rest.action.RestActions.NodesResponseRestListener;
2120
import org.elasticsearch.rest.action.RestCancellableNodeClient;
21+
import org.elasticsearch.rest.action.RestChunkedToXContentListener;
2222

2323
import java.io.IOException;
2424
import java.util.Collections;
@@ -33,7 +33,7 @@
3333
import static org.elasticsearch.rest.RestRequest.Method.GET;
3434

3535
public class RestNodesStatsAction extends BaseRestHandler {
36-
private DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RestNodesStatsAction.class);
36+
private final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RestNodesStatsAction.class);
3737
private static final String TYPES_DEPRECATION_MESSAGE = "[types removal] " + "Specifying types in nodes stats requests is deprecated.";
3838

3939
@Override
@@ -182,7 +182,7 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
182182

183183
return channel -> new RestCancellableNodeClient(client, request.getHttpChannel()).admin()
184184
.cluster()
185-
.nodesStats(nodesStatsRequest, new NodesResponseRestListener<>(channel));
185+
.nodesStats(nodesStatsRequest, new RestChunkedToXContentListener<>(channel));
186186
}
187187

188188
private final Set<String> RESPONSE_PARAMS = Collections.singleton("level");

0 commit comments

Comments
 (0)