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

[4.x] - Add Context to Loom Webserver. #5593

Merged
merged 7 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ public RoutingRequest prologue(HttpPrologue newPrologue) {
public Context context() {
if (context == null) {
context = Contexts.context().orElseGet(() -> Context.builder()
.id("[" + serverSocketId() + " " + socketId() + "] http/2: " + requestId)
.parent(ctx.context())
.id("[" + serverSocketId() + " " + socketId() + "] http/1.1: " + requestId)
.build());
}
return context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.helidon.common.buffers.BufferData;
import io.helidon.common.buffers.DataReader;
import io.helidon.common.buffers.DataWriter;
import io.helidon.common.context.Context;
import io.helidon.common.socket.PeerInfo;
import io.helidon.nima.http.encoding.ContentEncodingContext;
import io.helidon.nima.http.media.MediaContext;
Expand Down Expand Up @@ -152,7 +153,8 @@ private void startServer() {
"unit-channel",
DirectHandlers.builder().build(),
socket,
-1);
-1,
Context.create());

ServerConnection connection = Http1ConnectionProvider.builder()
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import io.helidon.common.buffers.DataReader;
import io.helidon.common.buffers.DataWriter;
import io.helidon.common.context.Context;
import io.helidon.common.socket.HelidonSocket;
import io.helidon.common.socket.SocketContext;
import io.helidon.nima.http.encoding.ContentEncodingContext;
Expand All @@ -44,6 +45,7 @@ public interface ConnectionContext extends SocketContext {
* @param simpleHandlers error handling configuration
* @param socket socket to obtain information about peers
* @param maxPayloadSize maximal size of a payload entity
* @param context parent context from web server
* @return a new context
*/
static ConnectionContext create(MediaContext mediaContext,
Expand All @@ -56,7 +58,8 @@ static ConnectionContext create(MediaContext mediaContext,
String channelId,
DirectHandlers simpleHandlers,
HelidonSocket socket,
long maxPayloadSize) {
long maxPayloadSize,
Context context) {
return new ConnectionContextImpl(mediaContext,
contentEncodingContext,
sharedExecutor,
Expand All @@ -67,7 +70,8 @@ static ConnectionContext create(MediaContext mediaContext,
channelId,
simpleHandlers,
socket,
maxPayloadSize);
maxPayloadSize,
context);
}

/**
Expand Down Expand Up @@ -125,4 +129,11 @@ static ConnectionContext create(MediaContext mediaContext,
* @return simple handlers
*/
DirectHandlers directHandlers();

/**
* Parent context from WebServer.
*
* @return parent context.
*/
Context context();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import io.helidon.common.buffers.DataReader;
import io.helidon.common.buffers.DataWriter;
import io.helidon.common.context.Context;
import io.helidon.common.socket.HelidonSocket;
import io.helidon.common.socket.PeerInfo;
import io.helidon.nima.http.encoding.ContentEncodingContext;
Expand All @@ -39,6 +40,7 @@ final class ConnectionContextImpl implements ConnectionContext {
private final DirectHandlers simpleHandlers;
private final HelidonSocket socket;
private final long maxPayloadSize;
private final Context context;

ConnectionContextImpl(MediaContext mediaContext,
ContentEncodingContext contentEncodingContext,
Expand All @@ -50,7 +52,8 @@ final class ConnectionContextImpl implements ConnectionContext {
String childSocketId,
DirectHandlers simpleHandlers,
HelidonSocket socket,
long maxPayloadSize) {
long maxPayloadSize,
Context context) {
this.mediaContext = mediaContext;
this.contentEncodingContext = contentEncodingContext;
this.sharedExecutor = sharedExecutor;
Expand All @@ -62,6 +65,7 @@ final class ConnectionContextImpl implements ConnectionContext {
this.simpleHandlers = simpleHandlers;
this.socket = socket;
this.maxPayloadSize = maxPayloadSize;
this.context = context;
}

@Override
Expand Down Expand Up @@ -129,13 +133,18 @@ public String childSocketId() {
return childSocketId;
}

@Override
public Context context() {
return context;
}

@Override
public int hashCode() {
return Objects.hash(sharedExecutor,
dataWriter,
router,
socketId,
childSocketId);
dataWriter,
router,
socketId,
childSocketId);
}

@Override
Expand Down Expand Up @@ -163,5 +172,4 @@ public String toString() {
+ "socketId=" + socketId + ", "
+ "childSocketId=" + childSocketId + ']';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import io.helidon.common.buffers.BufferData;
import io.helidon.common.buffers.DataReader;
import io.helidon.common.context.Context;
import io.helidon.common.http.HttpException;
import io.helidon.common.http.RequestException;
import io.helidon.common.socket.HelidonSocket;
Expand Down Expand Up @@ -65,7 +66,8 @@ class ConnectionHandler implements Runnable {
Router router,
int writeQueueLength,
long maxPayloadSize,
DirectHandlers simpleHandlers) {
DirectHandlers simpleHandlers,
Context context) {
this.connectionProviders = connectionProviders;
this.providerCandidates = connectionProviders.providerCandidates();
this.serverChannelId = serverChannelId;
Expand All @@ -83,7 +85,8 @@ class ConnectionHandler implements Runnable {
channelId,
simpleHandlers,
socket,
maxPayloadSize);
maxPayloadSize,
context);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.function.Consumer;

import io.helidon.common.Version;
import io.helidon.common.context.Context;
import io.helidon.nima.http.encoding.ContentEncodingContext;
import io.helidon.nima.http.media.MediaContext;
import io.helidon.nima.webserver.http.DirectHandlers;
Expand All @@ -51,6 +52,8 @@ class LoomServer implements WebServer {
private volatile List<ListenerFuture> startFutures;
private boolean alreadyStarted = false;

private final Context context;

LoomServer(Builder builder, DirectHandlers simpleHandlers) {
List<ServerConnectionProvider> connectionProviders = builder.connectionProviders();

Expand Down Expand Up @@ -99,6 +102,7 @@ class LoomServer implements WebServer {
.allowSetThreadLocals(true)
.inheritInheritableThreadLocals(false)
.factory());
this.context = builder.context();
}

@Override
Expand Down Expand Up @@ -161,6 +165,11 @@ public boolean hasTls(String socketName) {
return false;
}

@Override
public Context context() {
return context;
}

private void stopIt() {
parallel("stop", ServerListener::stop);
running.set(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ private void listen() {
router,
listenerConfig.writeQueueLength(),
listenerConfig.maxPayloadSize(),
simpleHandlers);
simpleHandlers,
server.context());

readerExecutor.submit(handler);
} catch (RejectedExecutionException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

import io.helidon.common.HelidonServiceLoader;
import io.helidon.common.context.Context;
import io.helidon.common.http.DirectHandler;
import io.helidon.config.Config;
import io.helidon.logging.common.LogConfig;
Expand Down Expand Up @@ -120,10 +122,20 @@ default boolean hasTls() {
*/
boolean hasTls(String socketName);

/**
* Context associated with the {@code WebServer}, used as a parent for request contexts.
*
* @return a server context
*/
Context context();

/**
* Fluent API builder for {@link WebServer}.
*/
class Builder implements io.helidon.common.Builder<Builder, WebServer>, Router.RouterBuilder<Builder> {

private static final AtomicInteger WEBSERVER_COUNTER = new AtomicInteger(1);

static {
LogConfig.initClass();
}
Expand All @@ -138,6 +150,8 @@ class Builder implements io.helidon.common.Builder<Builder, WebServer>, Router.R
private MediaContext mediaContext = MediaContext.create();
private ContentEncodingContext contentEncodingContext = ContentEncodingContext.create();

private Context context;

Builder(Config rootConfig) {
config(rootConfig.get("server"));
}
Expand All @@ -149,6 +163,15 @@ private Builder() {

@Override
public WebServer build() {

if (context == null) {
// In case somebody spins a huge number up, the counter will cycle to negative numbers once
// Integer.MAX_VALUE is reached.
context = Context.builder()
.id("web-" + WEBSERVER_COUNTER.getAndIncrement())
.build();
}

return new LoomServer(this, simpleHandlers.build());
}

Expand Down Expand Up @@ -380,6 +403,20 @@ public Builder contentEncodingContext(ContentEncodingContext contentEncodingCont
return this;
}

/**
* Configure the application scoped context to be used as a parent for webserver request contexts.
* @param context top level context
* @return an updated builder
*/
public Builder context(Context context) {
this.context = context;
return this;
}

Context context() {
return context;
}

MediaContext mediaContext() {
return this.mediaContext;
}
Expand All @@ -391,7 +428,6 @@ ContentEncodingContext contentEncodingContext() {
Map<String, ListenerConfiguration.Builder> socketBuilders() {
return socketBuilder;
}

/**
* Map of socket name to router.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ public Http1ServerRequest prologue(HttpPrologue newPrologue) {
public Context context() {
if (context == null) {
context = Contexts.context().orElseGet(() -> Context.builder()
.parent(ctx.context())
.id("[" + serverSocketId() + " " + socketId() + "] http/1.1: " + requestId)
.build());
}
Expand Down