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
26c3abc63c
commit
84cf8f14e9
@ -45,6 +45,9 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
private final Channel channel;
|
private final Channel channel;
|
||||||
private volatile ChannelHandler handler;
|
private volatile ChannelHandler handler;
|
||||||
|
|
||||||
|
// Cache the ChannelHandlerContext to speed up open(...) operations.
|
||||||
|
private volatile ChannelHandlerContext multiplexCtx;
|
||||||
|
|
||||||
public Http2StreamChannelBootstrap(Channel channel) {
|
public Http2StreamChannelBootstrap(Channel channel) {
|
||||||
this.channel = ObjectUtil.checkNotNull(channel, "channel");
|
this.channel = ObjectUtil.checkNotNull(channel, "channel");
|
||||||
}
|
}
|
||||||
@ -113,18 +116,8 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public Future<Http2StreamChannel> open(final Promise<Http2StreamChannel> promise) {
|
public Future<Http2StreamChannel> open(final Promise<Http2StreamChannel> promise) {
|
||||||
ChannelHandlerContext ctx = channel.pipeline().context(Http2MultiplexCodec.class);
|
try {
|
||||||
if (ctx == null) {
|
ChannelHandlerContext ctx = findCtx();
|
||||||
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 {
|
|
||||||
EventExecutor executor = ctx.executor();
|
EventExecutor executor = ctx.executor();
|
||||||
if (executor.inEventLoop()) {
|
if (executor.inEventLoop()) {
|
||||||
open0(ctx, promise);
|
open0(ctx, promise);
|
||||||
@ -137,10 +130,36 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} catch (Throwable cause) {
|
||||||
|
promise.setFailure(cause);
|
||||||
}
|
}
|
||||||
return promise;
|
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 should not be used directly. Use {@link #open()} or {@link #open(Promise)}
|
||||||
*/
|
*/
|
||||||
@ -164,7 +183,7 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
ChannelFuture future = ctx.channel().eventLoop().register(streamChannel);
|
ChannelFuture future = ctx.channel().eventLoop().register(streamChannel);
|
||||||
future.addListener(new ChannelFutureListener() {
|
future.addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
public void operationComplete(ChannelFuture future) {
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
promise.setSuccess(streamChannel);
|
promise.setSuccess(streamChannel);
|
||||||
} else if (future.isCancelled()) {
|
} else if (future.isCancelled()) {
|
||||||
@ -183,7 +202,7 @@ public final class Http2StreamChannelBootstrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void init(Channel channel) throws Exception {
|
private void init(Channel channel) {
|
||||||
ChannelPipeline p = channel.pipeline();
|
ChannelPipeline p = channel.pipeline();
|
||||||
ChannelHandler handler = this.handler;
|
ChannelHandler handler = this.handler;
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user