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

Extract common http logic to server #31311

Merged
merged 31 commits into from
Jun 14, 2018

Conversation

Tim-Brooks
Copy link
Contributor

This is related to #28898. With the addition of the http nio transport,
we now have two different modules that provide http transports.
Currently most of the http logic lives at the module level. However,
some of this logic can live in server. In particular, some of the
setting of headers, cors, and pipelining. This commit begins this moving
in that direction by introducing lower level abstraction (HttpChannel,
HttpRequest, and HttpResonse) that is implemented by the modules. The
higher level rest request and rest channel work can live entirely in
server.

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@Tim-Brooks
Copy link
Contributor Author

The idea here is that there are now single implementations of RestRequest and RestChannel (technically there are multiple RestChannel implementations - but a single instance DefaultRestChannel is the most important one - opposed to separate implementations per module). Instead of implementing those classes, the lower level http modules provide a HttpChannel (similar to how the transport module provide a TcpChannel). This HttpChannel is connection based, opposed to a different one per request.

Additionally module provide lightweight HttpRequest implementations that allow accessing headers, uri, content, etc and a lightweight HttpResponse that allows setting headers. All of the logic for decoding params, setting headers, etc now lives in AbstractHttpServerTransport and DefaultRestChannel.

Eventually the cors logic and pipelining logic should be moved to server.

@s1monw
Copy link
Contributor

s1monw commented Jun 14, 2018

meh 2k SLoC - I will try...

Copy link
Contributor

@s1monw s1monw left a comment

Choose a reason for hiding this comment

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

I do like that we are sharing lots of stuff now. I left some comments on the way mainly style etc. LGTM in general, thanks for doing this

ch.pipeline().addLast("logging", new ESLoggingHandler());
ch.pipeline().addLast("size", new Netty4SizeHeaderFrameDecoder());
ch.pipeline().addLast("dispatcher", new Netty4MessageChannelHandler(Netty4Transport.this, name));
serverAcceptedChannel(nettyTcpChannel);
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@@ -98,8 +98,11 @@ public void sendMessage(BytesReference reference, ActionListener<Void> listener)
} else {
final Throwable cause = f.cause();
Netty4Utils.maybeDie(cause);
assert cause instanceof Exception;
listener.onFailure((Exception) cause);
if (cause instanceof Error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

wait, what error can get past Netty4Utils.maybeDie(cause);?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

None. Elasticsearch should still die on another thread. We just have to do something on this thread in the meantime. In the old version the assertion would only trigger is assertions were enabled. And then it would throw a class cast exception.

I mean this is super edge case, but I thought that elasticsearch dying on another thread would handle the Error and on this thread we would just continue on in the meantime.

}

static {
EnumMap<RestStatus, HttpResponseStatus> map = new EnumMap<>(RestStatus.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

can we somehow share this ? I saw it in multiple places now. maybe in HttpResponse?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes using the status code (int). I'll do that in a followup though.

*/
package org.elasticsearch.http;

public abstract class AbstractHttpPipelinedMessage implements HttpPipelinedMessage {
Copy link
Contributor

Choose a reason for hiding this comment

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

this only has a single implementation. can we fold it into it?

@@ -81,6 +90,10 @@ protected AbstractHttpServerTransport(Settings settings, NetworkService networkS
this.maxContentLength = SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings);
}

public BigArrays getBigArrays() {
Copy link
Contributor

Choose a reason for hiding this comment

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

can this be protected?

public int getSequence() {
return sequence;
}
int getSequence();
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure what this is supposed to return. can you add javadocs?

Copy link
Contributor

Choose a reason for hiding this comment

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

from my guessing I wonder if we should name it getOrd()


package org.elasticsearch.http;

public interface HttpResponse {
Copy link
Contributor

Choose a reason for hiding this comment

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

javadocs pls

import java.util.List;
import java.util.Map;

public interface HttpRequest {
Copy link
Contributor

Choose a reason for hiding this comment

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

javadocs pls

@Nullable
public SocketAddress getRemoteAddress() {
return null;
public InetSocketAddress getRemoteAddress() {
Copy link
Contributor

Choose a reason for hiding this comment

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

would it make sense to let the consumer just call getHttpChannel and then get from it what they need instead of having these delegates?

*/
@Nullable
public Map<String, List<String>> getHeaders() {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@Tim-Brooks Tim-Brooks merged commit fcf1e41 into elastic:master Jun 14, 2018
tlrx added a commit that referenced this pull request Jun 15, 2018
* master:
  992c788 Uncouple persistent task state and status (#31031)
  8c6ee7d Describe how to add a plugin in Dockerfile (#31340)
  1c5cec0 Remove http status code maps (#31350)
  87a676e Do not set vm.max_map_count when unnecessary (#31285)
  e5b7137 TEST: getCapturedRequestsAndClear should be atomic (#31312)
  0324103 Painless: Fix bug for static method calls on interfaces (#31348)
  d6d0727 QA: Fix resolution of default distribution (#31351)
  fcf1e41 Extract common http logic to server (#31311)
  6dd81ea Build: Fix the license in the pom zip and tar (#31336)
  8f886cd Treat ack timeout more like a publish timeout (#31303)
  9b29327 [ML] Add description to ML filters (#31330)
  f7a0caf SQL: Fix build on Java 10
  375d09c [TEST] Fix RemoteClusterClientTests#testEnsureWeReconnect
  4877cec More detailed tracing when writing metadata (#31319)
  bbfe1ec [Tests] Mutualize fixtures code in BaseHttpFixture (#31210)
@Tim-Brooks Tim-Brooks deleted the default_rest_channel branch December 10, 2018 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed Coordination/Network Http and internode communication implementations >non-issue v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants