use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.
the class AbstractNettyHandler method sendInitialConnectionWindow.
/**
* Sends initial connection window to the remote endpoint if necessary.
*/
private void sendInitialConnectionWindow() throws Http2Exception {
if (ctx.channel().isActive() && initialConnectionWindow > 0) {
Http2Stream connectionStream = connection().connectionStream();
int currentSize = connection().local().flowController().windowSize(connectionStream);
int delta = initialConnectionWindow - currentSize;
decoder().flowController().incrementWindowSize(connectionStream, delta);
initialConnectionWindow = -1;
ctx.flush();
}
}
use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.
the class NettyClientHandler method forcefulClose.
private void forcefulClose(final ChannelHandlerContext ctx, final ForcefulCloseCommand msg, ChannelPromise promise) throws Exception {
lifecycleManager.notifyShutdown(Status.UNAVAILABLE.withDescription("Channel requested transport to shut down"));
close(ctx, promise);
connection().forEachActiveStream(new Http2StreamVisitor() {
@Override
public boolean visit(Http2Stream stream) throws Http2Exception {
NettyClientStream.TransportState clientStream = clientStream(stream);
if (clientStream != null) {
clientStream.transportReportStatus(msg.getStatus(), true, new Metadata());
resetStream(ctx, stream.id(), Http2Error.CANCEL.code(), ctx.newPromise());
}
stream.close();
return true;
}
});
}
use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.
the class NettyClientHandler method createStream.
/**
* Attempts to create a new stream from the given command. If there are too many active streams,
* the creation request is queued.
*/
private void createStream(CreateStreamCommand command, final ChannelPromise promise) throws Exception {
if (lifecycleManager.getShutdownThrowable() != null) {
// The connection is going away, just terminate the stream now.
promise.setFailure(lifecycleManager.getShutdownThrowable());
return;
}
// Get the stream ID for the new stream.
final int streamId;
try {
streamId = incrementAndGetNextStreamId();
} catch (StatusException e) {
// Stream IDs have been exhausted for this connection. Fail the promise immediately.
promise.setFailure(e);
// Initiate a graceful shutdown if we haven't already.
if (!connection().goAwaySent()) {
logger.fine("Stream IDs have been exhausted for this connection. " + "Initiating graceful shutdown of the connection.");
lifecycleManager.notifyShutdown(e.getStatus());
close(ctx(), ctx().newPromise());
}
return;
}
final NettyClientStream.TransportState stream = command.stream();
final Http2Headers headers = command.headers();
stream.setId(streamId);
// Create an intermediate promise so that we can intercept the failure reported back to the
// application.
ChannelPromise tempPromise = ctx().newPromise();
encoder().writeHeaders(ctx(), streamId, headers, 0, false, tempPromise).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
// The http2Stream will be null in case a stream buffered in the encoder
// was canceled via RST_STREAM.
Http2Stream http2Stream = connection().stream(streamId);
if (http2Stream != null) {
stream.getStatsTraceContext().clientHeadersSent();
http2Stream.setProperty(streamKey, stream);
// Attach the client stream to the HTTP/2 stream object as user data.
stream.setHttp2Stream(http2Stream);
}
// Otherwise, the stream has been cancelled and Netty is sending a
// RST_STREAM frame which causes it to purge pending writes from the
// flow-controller and delete the http2Stream. The stream listener has already
// been notified of cancellation so there is nothing to do.
// Just forward on the success status to the original promise.
promise.setSuccess();
} else {
final Throwable cause = future.cause();
if (cause instanceof StreamBufferingEncoder.Http2GoAwayException) {
StreamBufferingEncoder.Http2GoAwayException e = (StreamBufferingEncoder.Http2GoAwayException) cause;
lifecycleManager.notifyShutdown(statusFromGoAway(e.errorCode(), e.debugData()));
promise.setFailure(lifecycleManager.getShutdownThrowable());
} else {
promise.setFailure(cause);
}
}
}
});
}
use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.
the class NettyClientHandler method channelInactive.
/**
* Handler for the Channel shutting down.
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
try {
logger.fine("Network channel is closed");
lifecycleManager.notifyShutdown(Status.UNAVAILABLE.withDescription("Network closed for unknown reason"));
cancelPing(lifecycleManager.getShutdownThrowable());
// Report status to the application layer for any open streams
connection().forEachActiveStream(new Http2StreamVisitor() {
@Override
public boolean visit(Http2Stream stream) throws Http2Exception {
NettyClientStream.TransportState clientStream = clientStream(stream);
if (clientStream != null) {
clientStream.transportReportStatus(lifecycleManager.getShutdownStatus(), false, new Metadata());
}
return true;
}
});
} finally {
// Close any open streams
super.channelInactive(ctx);
if (keepAliveManager != null) {
keepAliveManager.onTransportShutdown();
}
}
}
use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.
the class NettyHandlerTestBase method windowShouldNotExceedMaxWindowSize.
@Test
public void windowShouldNotExceedMaxWindowSize() throws Exception {
makeStream();
AbstractNettyHandler handler = (AbstractNettyHandler) handler();
handler.setAutoTuneFlowControl(true);
Http2Stream connectionStream = connection().connectionStream();
Http2LocalFlowController localFlowController = connection().local().flowController();
int maxWindow = handler.flowControlPing().maxWindow();
handler.flowControlPing().setDataSizeSincePing(maxWindow);
int payload = handler.flowControlPing().payload();
ByteBuf buffer = handler.ctx().alloc().buffer(8);
buffer.writeLong(payload);
channelRead(pingFrame(true, buffer));
assertEquals(maxWindow, localFlowController.initialWindowSize(connectionStream));
}
Aggregations