Skip to content

Commit 4fd0a3e

Browse files
colings86Tim-Brooks
authored andcommitted
Revert "Make http pipelining support mandatory (#30695)" (#30813)
This reverts commit 31251c9 introduced in #30695. We suspect this commit is causing the OOME's reported in #30811 and we will use this PR to test this assertion.
1 parent ab047ca commit 4fd0a3e

File tree

38 files changed

+669
-1002
lines changed

38 files changed

+669
-1002
lines changed

docs/reference/migration/migrate_7_0/settings.asciidoc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@
2929
[[remove-http-enabled]]
3030
==== Http enabled setting removed
3131

32-
* The setting `http.enabled` previously allowed disabling binding to HTTP, only allowing
32+
The setting `http.enabled` previously allowed disabling binding to HTTP, only allowing
3333
use of the transport client. This setting has been removed, as the transport client
3434
will be removed in the future, thus requiring HTTP to always be enabled.
35-
36-
[[remove-http-pipelining-setting]]
37-
==== Http pipelining setting removed
38-
39-
* The setting `http.pipelining` previously allowed disabling HTTP pipelining support.
40-
This setting has been removed, as disabling http pipelining support on the server
41-
provided little value. The setting `http.pipelining.max_events` can still be used to
42-
limit the number of pipelined requests in-flight.

docs/reference/modules/http.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ and stack traces in response output. Note: When set to `false` and the `error_tr
9696
parameter is specified, an error will be returned; when `error_trace` is not specified, a
9797
simple message will be returned. Defaults to `true`
9898

99+
|`http.pipelining` |Enable or disable HTTP pipelining, defaults to `true`.
100+
99101
|`http.pipelining.max_events` |The maximum number of events to be queued up in memory before a HTTP connection is closed, defaults to `10000`.
100102

101103
|`http.max_warning_header_count` |The maximum number of warning headers in

modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/Netty4HttpChannel.java

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.elasticsearch.common.util.concurrent.ThreadContext;
4343
import org.elasticsearch.http.HttpHandlingSettings;
4444
import org.elasticsearch.http.netty4.cors.Netty4CorsHandler;
45+
import org.elasticsearch.http.netty4.pipelining.HttpPipelinedRequest;
4546
import org.elasticsearch.rest.AbstractRestChannel;
4647
import org.elasticsearch.rest.RestResponse;
4748
import org.elasticsearch.rest.RestStatus;
@@ -58,24 +59,29 @@ final class Netty4HttpChannel extends AbstractRestChannel {
5859
private final Netty4HttpServerTransport transport;
5960
private final Channel channel;
6061
private final FullHttpRequest nettyRequest;
61-
private final int sequence;
62+
private final HttpPipelinedRequest pipelinedRequest;
6263
private final ThreadContext threadContext;
6364
private final HttpHandlingSettings handlingSettings;
6465

6566
/**
66-
* @param transport The corresponding <code>NettyHttpServerTransport</code> where this channel belongs to.
67-
* @param request The request that is handled by this channel.
68-
* @param sequence The pipelining sequence number for this request
69-
* @param handlingSettings true if error messages should include stack traces.
70-
* @param threadContext the thread context for the channel
67+
* @param transport The corresponding <code>NettyHttpServerTransport</code> where this channel belongs to.
68+
* @param request The request that is handled by this channel.
69+
* @param pipelinedRequest If HTTP pipelining is enabled provide the corresponding pipelined request. May be null if
70+
* HTTP pipelining is disabled.
71+
* @param handlingSettings true iff error messages should include stack traces.
72+
* @param threadContext the thread context for the channel
7173
*/
72-
Netty4HttpChannel(Netty4HttpServerTransport transport, Netty4HttpRequest request, int sequence, HttpHandlingSettings handlingSettings,
73-
ThreadContext threadContext) {
74+
Netty4HttpChannel(
75+
final Netty4HttpServerTransport transport,
76+
final Netty4HttpRequest request,
77+
final HttpPipelinedRequest pipelinedRequest,
78+
final HttpHandlingSettings handlingSettings,
79+
final ThreadContext threadContext) {
7480
super(request, handlingSettings.getDetailedErrorsEnabled());
7581
this.transport = transport;
7682
this.channel = request.getChannel();
7783
this.nettyRequest = request.request();
78-
this.sequence = sequence;
84+
this.pipelinedRequest = pipelinedRequest;
7985
this.threadContext = threadContext;
8086
this.handlingSettings = handlingSettings;
8187
}
@@ -123,7 +129,7 @@ public void sendResponse(RestResponse response) {
123129
final ChannelPromise promise = channel.newPromise();
124130

125131
if (releaseContent) {
126-
promise.addListener(f -> ((Releasable) content).close());
132+
promise.addListener(f -> ((Releasable)content).close());
127133
}
128134

129135
if (releaseBytesStreamOutput) {
@@ -134,9 +140,13 @@ public void sendResponse(RestResponse response) {
134140
promise.addListener(ChannelFutureListener.CLOSE);
135141
}
136142

137-
Netty4HttpResponse newResponse = new Netty4HttpResponse(sequence, resp);
138-
139-
channel.writeAndFlush(newResponse, promise);
143+
final Object msg;
144+
if (pipelinedRequest != null) {
145+
msg = pipelinedRequest.createHttpResponse(resp, promise);
146+
} else {
147+
msg = resp;
148+
}
149+
channel.writeAndFlush(msg, promise);
140150
releaseContent = false;
141151
releaseBytesStreamOutput = false;
142152
} finally {
@@ -146,6 +156,9 @@ public void sendResponse(RestResponse response) {
146156
if (releaseBytesStreamOutput) {
147157
bytesOutputOrNull().close();
148158
}
159+
if (pipelinedRequest != null) {
160+
pipelinedRequest.release();
161+
}
149162
}
150163
}
151164

modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/Netty4HttpPipeliningHandler.java

Lines changed: 0 additions & 102 deletions
This file was deleted.

modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/Netty4HttpRequestHandler.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,41 @@
3030
import io.netty.handler.codec.http.HttpHeaders;
3131
import org.elasticsearch.common.util.concurrent.ThreadContext;
3232
import org.elasticsearch.http.HttpHandlingSettings;
33-
import org.elasticsearch.http.HttpPipelinedRequest;
33+
import org.elasticsearch.http.netty4.pipelining.HttpPipelinedRequest;
3434
import org.elasticsearch.rest.RestRequest;
3535
import org.elasticsearch.transport.netty4.Netty4Utils;
3636

3737
import java.util.Collections;
3838

3939
@ChannelHandler.Sharable
40-
class Netty4HttpRequestHandler extends SimpleChannelInboundHandler<HttpPipelinedRequest<FullHttpRequest>> {
40+
class Netty4HttpRequestHandler extends SimpleChannelInboundHandler<Object> {
4141

4242
private final Netty4HttpServerTransport serverTransport;
4343
private final HttpHandlingSettings handlingSettings;
44+
private final boolean httpPipeliningEnabled;
4445
private final ThreadContext threadContext;
4546

4647
Netty4HttpRequestHandler(Netty4HttpServerTransport serverTransport, HttpHandlingSettings handlingSettings,
4748
ThreadContext threadContext) {
4849
this.serverTransport = serverTransport;
50+
this.httpPipeliningEnabled = serverTransport.pipelining;
4951
this.handlingSettings = handlingSettings;
5052
this.threadContext = threadContext;
5153
}
5254

5355
@Override
54-
protected void channelRead0(ChannelHandlerContext ctx, HttpPipelinedRequest<FullHttpRequest> msg) throws Exception {
55-
final FullHttpRequest request = msg.getRequest();
56+
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
57+
final FullHttpRequest request;
58+
final HttpPipelinedRequest pipelinedRequest;
59+
if (this.httpPipeliningEnabled && msg instanceof HttpPipelinedRequest) {
60+
pipelinedRequest = (HttpPipelinedRequest) msg;
61+
request = (FullHttpRequest) pipelinedRequest.last();
62+
} else {
63+
pipelinedRequest = null;
64+
request = (FullHttpRequest) msg;
65+
}
5666

67+
boolean success = false;
5768
try {
5869

5970
final FullHttpRequest copy =
@@ -100,7 +111,7 @@ protected void channelRead0(ChannelHandlerContext ctx, HttpPipelinedRequest<Full
100111
Netty4HttpChannel innerChannel;
101112
try {
102113
innerChannel =
103-
new Netty4HttpChannel(serverTransport, httpRequest, msg.getSequence(), handlingSettings, threadContext);
114+
new Netty4HttpChannel(serverTransport, httpRequest, pipelinedRequest, handlingSettings, threadContext);
104115
} catch (final IllegalArgumentException e) {
105116
if (badRequestCause == null) {
106117
badRequestCause = e;
@@ -115,7 +126,7 @@ protected void channelRead0(ChannelHandlerContext ctx, HttpPipelinedRequest<Full
115126
copy,
116127
ctx.channel());
117128
innerChannel =
118-
new Netty4HttpChannel(serverTransport, innerRequest, msg.getSequence(), handlingSettings, threadContext);
129+
new Netty4HttpChannel(serverTransport, innerRequest, pipelinedRequest, handlingSettings, threadContext);
119130
}
120131
channel = innerChannel;
121132
}
@@ -127,9 +138,12 @@ protected void channelRead0(ChannelHandlerContext ctx, HttpPipelinedRequest<Full
127138
} else {
128139
serverTransport.dispatchRequest(httpRequest, channel);
129140
}
141+
success = true;
130142
} finally {
131-
// As we have copied the buffer, we can release the request
132-
request.release();
143+
// the request is otherwise released in case of dispatch
144+
if (success == false && pipelinedRequest != null) {
145+
pipelinedRequest.release();
146+
}
133147
}
134148
}
135149

modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/Netty4HttpResponse.java

Lines changed: 0 additions & 37 deletions
This file was deleted.

modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/Netty4HttpServerTransport.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import org.elasticsearch.http.netty4.cors.Netty4CorsConfig;
6363
import org.elasticsearch.http.netty4.cors.Netty4CorsConfigBuilder;
6464
import org.elasticsearch.http.netty4.cors.Netty4CorsHandler;
65+
import org.elasticsearch.http.netty4.pipelining.HttpPipeliningHandler;
6566
import org.elasticsearch.rest.RestUtils;
6667
import org.elasticsearch.threadpool.ThreadPool;
6768
import org.elasticsearch.transport.netty4.Netty4OpenChannelsHandler;
@@ -98,6 +99,7 @@
9899
import static org.elasticsearch.http.HttpTransportSettings.SETTING_HTTP_TCP_RECEIVE_BUFFER_SIZE;
99100
import static org.elasticsearch.http.HttpTransportSettings.SETTING_HTTP_TCP_REUSE_ADDRESS;
100101
import static org.elasticsearch.http.HttpTransportSettings.SETTING_HTTP_TCP_SEND_BUFFER_SIZE;
102+
import static org.elasticsearch.http.HttpTransportSettings.SETTING_PIPELINING;
101103
import static org.elasticsearch.http.HttpTransportSettings.SETTING_PIPELINING_MAX_EVENTS;
102104
import static org.elasticsearch.http.netty4.cors.Netty4CorsHandler.ANY_ORIGIN;
103105

@@ -160,6 +162,8 @@ public class Netty4HttpServerTransport extends AbstractHttpServerTransport {
160162

161163
protected final int workerCount;
162164

165+
protected final boolean pipelining;
166+
163167
protected final int pipeliningMaxEvents;
164168

165169
/**
@@ -200,16 +204,14 @@ public Netty4HttpServerTransport(Settings settings, NetworkService networkServic
200204
this.maxChunkSize = SETTING_HTTP_MAX_CHUNK_SIZE.get(settings);
201205
this.maxHeaderSize = SETTING_HTTP_MAX_HEADER_SIZE.get(settings);
202206
this.maxInitialLineLength = SETTING_HTTP_MAX_INITIAL_LINE_LENGTH.get(settings);
203-
this.pipeliningMaxEvents = SETTING_PIPELINING_MAX_EVENTS.get(settings);
204207
this.httpHandlingSettings = new HttpHandlingSettings(Math.toIntExact(maxContentLength.getBytes()),
205208
Math.toIntExact(maxChunkSize.getBytes()),
206209
Math.toIntExact(maxHeaderSize.getBytes()),
207210
Math.toIntExact(maxInitialLineLength.getBytes()),
208211
SETTING_HTTP_RESET_COOKIES.get(settings),
209212
SETTING_HTTP_COMPRESSION.get(settings),
210213
SETTING_HTTP_COMPRESSION_LEVEL.get(settings),
211-
SETTING_HTTP_DETAILED_ERRORS_ENABLED.get(settings),
212-
pipeliningMaxEvents);
214+
SETTING_HTTP_DETAILED_ERRORS_ENABLED.get(settings));
213215

214216
this.maxCompositeBufferComponents = SETTING_HTTP_NETTY_MAX_COMPOSITE_BUFFER_COMPONENTS.get(settings);
215217
this.workerCount = SETTING_HTTP_WORKER_COUNT.get(settings);
@@ -224,12 +226,14 @@ public Netty4HttpServerTransport(Settings settings, NetworkService networkServic
224226
ByteSizeValue receivePredictor = SETTING_HTTP_NETTY_RECEIVE_PREDICTOR_SIZE.get(settings);
225227
recvByteBufAllocator = new FixedRecvByteBufAllocator(receivePredictor.bytesAsInt());
226228

229+
this.pipelining = SETTING_PIPELINING.get(settings);
230+
this.pipeliningMaxEvents = SETTING_PIPELINING_MAX_EVENTS.get(settings);
227231
this.corsConfig = buildCorsConfig(settings);
228232

229233
logger.debug("using max_chunk_size[{}], max_header_size[{}], max_initial_line_length[{}], max_content_length[{}], " +
230-
"receive_predictor[{}], max_composite_buffer_components[{}], pipelining_max_events[{}]",
231-
maxChunkSize, maxHeaderSize, maxInitialLineLength, maxContentLength, receivePredictor, maxCompositeBufferComponents,
232-
pipeliningMaxEvents);
234+
"receive_predictor[{}], max_composite_buffer_components[{}], pipelining[{}], pipelining_max_events[{}]",
235+
maxChunkSize, maxHeaderSize, maxInitialLineLength, this.maxContentLength, receivePredictor, maxCompositeBufferComponents,
236+
pipelining, pipeliningMaxEvents);
233237
}
234238

235239
public Settings settings() {
@@ -448,7 +452,9 @@ protected void initChannel(Channel ch) throws Exception {
448452
if (SETTING_CORS_ENABLED.get(transport.settings())) {
449453
ch.pipeline().addLast("cors", new Netty4CorsHandler(transport.getCorsConfig()));
450454
}
451-
ch.pipeline().addLast("pipelining", new Netty4HttpPipeliningHandler(transport.logger, transport.pipeliningMaxEvents));
455+
if (transport.pipelining) {
456+
ch.pipeline().addLast("pipelining", new HttpPipeliningHandler(transport.logger, transport.pipeliningMaxEvents));
457+
}
452458
ch.pipeline().addLast("handler", requestHandler);
453459
}
454460

0 commit comments

Comments
 (0)