Skip to content

Commit e8f2df7

Browse files
committed
Optimize http headers creation
1 parent 8a1ca73 commit e8f2df7

File tree

6 files changed

+51
-39
lines changed

6 files changed

+51
-39
lines changed

frameworks/Java/netty/src/main/java/hello/HelloServerHandler.java

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package hello;
22

3-
import static hello.HttpResponses.makeJsonResponse;
4-
import static hello.HttpResponses.makePlaintextResponse;
3+
import static hello.HttpResponses.*;
54
import static hello.JsonUtils.acquireJsonStreamFromEventLoop;
65
import static hello.JsonUtils.releaseJsonStreamFromEventLoop;
76
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
@@ -19,11 +18,7 @@
1918
import io.netty.channel.ChannelFutureListener;
2019
import io.netty.channel.ChannelHandlerContext;
2120
import io.netty.channel.ChannelInboundHandlerAdapter;
22-
import io.netty.handler.codec.http.DefaultFullHttpResponse;
23-
import io.netty.handler.codec.http.DefaultHttpRequest;
24-
import io.netty.handler.codec.http.FullHttpResponse;
25-
import io.netty.handler.codec.http.HttpRequest;
26-
import io.netty.handler.codec.http.LastHttpContent;
21+
import io.netty.handler.codec.http.*;
2722
import io.netty.util.AsciiString;
2823
import io.netty.util.ReferenceCountUtil;
2924
import io.netty.util.concurrent.FastThreadLocal;
@@ -37,15 +32,18 @@ protected DateFormat initialValue() {
3732
}
3833
};
3934

40-
protected volatile AsciiString date = new AsciiString(FORMAT.get().format(new Date()));
35+
private HttpHeaders jsonHeaders = makeJsonHeaders(new AsciiString(FORMAT.get().format(new Date())));
36+
private HttpHeaders plaintextHeaders = makePlaintextHeaders(new AsciiString(FORMAT.get().format(new Date())));
4137

4238
public HelloServerHandler(ScheduledExecutorService service) {
4339
service.scheduleWithFixedDelay(new Runnable() {
4440
private final DateFormat format = FORMAT.get();
4541

4642
@Override
4743
public void run() {
48-
date = new AsciiString(format.format(new Date()));
44+
var date = new AsciiString(format.format(new Date()));
45+
jsonHeaders = makeJsonHeaders(date);
46+
plaintextHeaders = makePlaintextHeaders(date);
4947
}
5048
}, 1000, 1000, TimeUnit.MILLISECONDS);
5149
}
@@ -80,13 +78,13 @@ private void process(ChannelHandlerContext ctx, HttpRequest request) throws Exce
8078
String uri = request.uri();
8179
switch (uri) {
8280
case "/plaintext":
83-
writePlainResponse(ctx, date);
81+
writePlainResponse(ctx, plaintextHeaders);
8482
return;
8583
case "/json":
8684
// even for the virtual thread case we expect virtual threads to be executed inlined!
8785
var stream = acquireJsonStreamFromEventLoop();
8886
try {
89-
writeJsonResponse(ctx, stream, date);
87+
writeJsonResponse(ctx, stream, jsonHeaders);
9088
} finally {
9189
releaseJsonStreamFromEventLoop(stream);
9290
}
@@ -98,12 +96,12 @@ private void process(ChannelHandlerContext ctx, HttpRequest request) throws Exce
9896
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
9997
}
10098

101-
protected void writePlainResponse(ChannelHandlerContext ctx, AsciiString date) {
102-
ctx.write(makePlaintextResponse(date), ctx.voidPromise());
99+
protected void writePlainResponse(ChannelHandlerContext ctx, HttpHeaders plaintextHeaders) {
100+
ctx.write(makePlaintextResponse(plaintextHeaders), ctx.voidPromise());
103101
}
104102

105-
protected void writeJsonResponse(ChannelHandlerContext ctx, JsonStream stream, AsciiString date) {
106-
ctx.write(makeJsonResponse(stream, date), ctx.voidPromise());
103+
protected void writeJsonResponse(ChannelHandlerContext ctx, JsonStream stream, HttpHeaders jsonHeaders) {
104+
ctx.write(makeJsonResponse(stream, jsonHeaders), ctx.voidPromise());
107105
}
108106

109107
@Override

frameworks/Java/netty/src/main/java/hello/HelloServerInitializer.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414

1515
public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
1616

17-
protected final ScheduledExecutorService service;
18-
19-
public HelloServerInitializer(ScheduledExecutorService service) {
20-
this.service = service;
17+
public HelloServerInitializer() {
2118
}
2219

2320
@Override
@@ -46,7 +43,7 @@ protected boolean isContentAlwaysEmpty(final HttpMessage msg) {
4643
return false;
4744
}
4845
})
49-
.addLast("handler", newHelloServerHandler(service));
46+
.addLast("handler", newHelloServerHandler(ch.eventLoop()));
5047
}
5148

5249
protected HelloServerHandler newHelloServerHandler(ScheduledExecutorService service) {

frameworks/Java/netty/src/main/java/hello/HelloWebServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ public void run() throws Exception {
6767
}
6868
var channelB = b.group(group).channel(serverChannelClass);
6969
if (EVENT_LOOP_CARRIER) {
70-
channelB.childHandler(new HelloLoomServerInitializer((MultithreadVirtualEventExecutorGroup) group, group.next()));
70+
channelB.childHandler(new HelloLoomServerInitializer((MultithreadVirtualEventExecutorGroup) group));
7171
} else {
72-
channelB.childHandler(new HelloServerInitializer(group.next()));
72+
channelB.childHandler(new HelloServerInitializer());
7373
}
7474
b.childOption(ChannelOption.SO_REUSEADDR, true);
7575

frameworks/Java/netty/src/main/java/hello/HttpResponses.java

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,43 @@
2020
import io.netty.buffer.ByteBuf;
2121
import io.netty.buffer.Unpooled;
2222
import io.netty.handler.codec.http.DefaultFullHttpResponse;
23+
import io.netty.handler.codec.http.DefaultHttpHeadersFactory;
2324
import io.netty.handler.codec.http.FullHttpResponse;
25+
import io.netty.handler.codec.http.HttpHeaders;
26+
import io.netty.handler.codec.http.HttpHeadersFactory;
2427
import io.netty.util.AsciiString;
2528

2629
public class HttpResponses {
2730

28-
public static FullHttpResponse makePlaintextResponse(AsciiString date) {
29-
return makeResponse(Unpooled.wrappedBuffer(STATIC_PLAINTEXT), TEXT_PLAIN, PLAINTEXT_CLHEADER_VALUE, date);
30-
}
31+
private static final HttpHeadersFactory HEADERS_FACTORY = DefaultHttpHeadersFactory.headersFactory()
32+
.withValidation(false);
3133

32-
public static FullHttpResponse makeJsonResponse(JsonStream stream, AsciiString date) {
33-
return makeResponse(Unpooled.wrappedBuffer(serializeMsg(newMsg(), stream)), APPLICATION_JSON, JSON_CLHEADER_VALUE, date);
34+
public static HttpHeaders makeJsonHeaders(AsciiString date) {
35+
return HEADERS_FACTORY.newHeaders()
36+
.set(CONTENT_TYPE, APPLICATION_JSON)
37+
.set(SERVER, SERVER_NAME)
38+
.set(DATE, date)
39+
.set(CONTENT_LENGTH, JSON_CLHEADER_VALUE);
3440
}
3541

36-
private static FullHttpResponse makeResponse(ByteBuf buf, CharSequence contentType, CharSequence contentLength, AsciiString date) {
37-
final FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, buf, false);
38-
response.headers()
39-
.set(CONTENT_TYPE, contentType)
42+
43+
public static HttpHeaders makePlaintextHeaders(AsciiString date) {
44+
return HEADERS_FACTORY.newHeaders()
45+
.set(CONTENT_TYPE, TEXT_PLAIN)
4046
.set(SERVER, SERVER_NAME)
4147
.set(DATE, date)
42-
.set(CONTENT_LENGTH, contentLength);
43-
return response;
48+
.set(CONTENT_LENGTH, PLAINTEXT_CLHEADER_VALUE);
49+
}
50+
51+
public static FullHttpResponse makePlaintextResponse(HttpHeaders plaintextHeaders) {
52+
return makeResponse(Unpooled.wrappedBuffer(STATIC_PLAINTEXT), plaintextHeaders);
53+
}
54+
55+
public static FullHttpResponse makeJsonResponse(JsonStream stream, HttpHeaders jsonHeaders) {
56+
return makeResponse(Unpooled.wrappedBuffer(serializeMsg(newMsg(), stream)), jsonHeaders);
57+
}
58+
59+
private static FullHttpResponse makeResponse(ByteBuf buf, HttpHeaders headers) {
60+
return new DefaultFullHttpResponse(HTTP_1_1, OK, buf, headers, HttpHeaders.EMPTY_HEADERS);
4461
}
4562
}

frameworks/Java/netty/src/main/java/hello/loom/HelloLoomServerInitializer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ public class HelloLoomServerInitializer extends HelloServerInitializer {
99

1010
private final MultithreadVirtualEventExecutorGroup group;
1111

12-
public HelloLoomServerInitializer(MultithreadVirtualEventExecutorGroup group, ScheduledExecutorService service) {
13-
super(service);
12+
public HelloLoomServerInitializer(MultithreadVirtualEventExecutorGroup group) {
1413
this.group = group;
1514
}
1615

frameworks/Java/netty/src/main/java/hello/loom/VirtualThreadHelloServerHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import hello.HttpResponses;
1010
import io.netty.channel.ChannelHandlerContext;
1111
import io.netty.handler.codec.http.FullHttpResponse;
12+
import io.netty.handler.codec.http.HttpHeaders;
1213
import io.netty.util.AsciiString;
1314

1415
public class VirtualThreadHelloServerHandler extends HelloServerHandler {
@@ -22,16 +23,16 @@ public VirtualThreadHelloServerHandler(ScheduledExecutorService service, Multith
2223
}
2324

2425
@Override
25-
protected void writePlainResponse(ChannelHandlerContext ctx, AsciiString date) {
26+
protected void writePlainResponse(ChannelHandlerContext ctx, HttpHeaders plainTextHeaders) {
2627
group.eventLoopVirtualThreadFactory().newThread(() -> {
27-
responses.add(HttpResponses.makePlaintextResponse(date));
28+
responses.add(HttpResponses.makePlaintextResponse(plainTextHeaders));
2829
}).start();
2930
}
3031

3132
@Override
32-
protected void writeJsonResponse(ChannelHandlerContext ctx, JsonStream stream, AsciiString date) {
33+
protected void writeJsonResponse(ChannelHandlerContext ctx, JsonStream stream, HttpHeaders jsonHeaders) {
3334
group.eventLoopVirtualThreadFactory().newThread(() -> {
34-
responses.add(HttpResponses.makeJsonResponse(stream, date));
35+
responses.add(HttpResponses.makeJsonResponse(stream, jsonHeaders));
3536
}).start();
3637
}
3738

0 commit comments

Comments
 (0)