Cache the ChannelHandlerContext used in Http2StreamChannelBootstrap (#9382)
Motivation: At the moment we lookup the ChannelHandlerContext used in Http2StreamChannelBootstrap each time the open(...) method is invoked. This is not needed and we can just cache it for later usage. Modifications: Cache ChannelHandlerContext in volatile field. Result: Speed up open(...) method implementation when called multiple times
This commit is contained in:
parent
2ef4b16138
commit
82ac20bec0
@ -46,6 +46,9 @@ public final class Http2StreamChannelBootstrap {
|
||||
private final Channel channel;
|
||||
private volatile ChannelHandler handler;
|
||||
|
||||
// Cache the ChannelHandlerContext to speed up open(...) operations.
|
||||
private volatile ChannelHandlerContext multiplexCtx;
|
||||
|
||||
public Http2StreamChannelBootstrap(Channel channel) {
|
||||
this.channel = requireNonNull(channel, "channel");
|
||||
}
|
||||
@ -110,18 +113,8 @@ public final class Http2StreamChannelBootstrap {
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public Future<Http2StreamChannel> open(final Promise<Http2StreamChannel> promise) {
|
||||
ChannelHandlerContext ctx = channel.pipeline().context(Http2MultiplexCodec.class);
|
||||
if (ctx == null) {
|
||||
ctx = channel.pipeline().context(Http2MultiplexHandler.class);
|
||||
}
|
||||
if (ctx == null) {
|
||||
if (channel.isActive()) {
|
||||
promise.setFailure(new IllegalStateException(StringUtil.simpleClassName(Http2MultiplexCodec.class) +
|
||||
" must be in the ChannelPipeline of Channel " + channel));
|
||||
} else {
|
||||
promise.setFailure(new ClosedChannelException());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
ChannelHandlerContext ctx = findCtx();
|
||||
EventExecutor executor = ctx.executor();
|
||||
if (executor.inEventLoop()) {
|
||||
open0(ctx, promise);
|
||||
@ -129,13 +122,39 @@ public final class Http2StreamChannelBootstrap {
|
||||
final ChannelHandlerContext finalCtx = ctx;
|
||||
executor.execute(() -> open0(finalCtx, promise));
|
||||
}
|
||||
} catch (Throwable cause) {
|
||||
promise.setFailure(cause);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
private ChannelHandlerContext findCtx() throws ClosedChannelException {
|
||||
// First try to use cached context and if this not work lets try to lookup the context.
|
||||
ChannelHandlerContext ctx = this.multiplexCtx;
|
||||
if (ctx != null && !ctx.isRemoved()) {
|
||||
return ctx;
|
||||
}
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
ctx = pipeline.context(Http2MultiplexCodec.class);
|
||||
if (ctx == null) {
|
||||
ctx = pipeline.context(Http2MultiplexHandler.class);
|
||||
}
|
||||
if (ctx == null) {
|
||||
if (channel.isActive()) {
|
||||
throw new IllegalStateException(StringUtil.simpleClassName(Http2MultiplexCodec.class) + " or "
|
||||
+ StringUtil.simpleClassName(Http2MultiplexHandler.class)
|
||||
+ " must be in the ChannelPipeline of Channel " + channel);
|
||||
} else {
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
}
|
||||
this.multiplexCtx = ctx;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated should not be used directly. Use {@link #open()} or {@link #open(Promise)}
|
||||
*/
|
||||
*/
|
||||
@Deprecated
|
||||
public void open0(ChannelHandlerContext ctx, final Promise<Http2StreamChannel> promise) {
|
||||
assert ctx.executor().inEventLoop();
|
||||
@ -172,7 +191,7 @@ public final class Http2StreamChannelBootstrap {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void init(Channel channel) throws Exception {
|
||||
private void init(Channel channel) {
|
||||
ChannelPipeline p = channel.pipeline();
|
||||
ChannelHandler handler = this.handler;
|
||||
if (handler != null) {
|
||||
|
Loading…
Reference in New Issue
Block a user