io.netty.handler.codec.http2.Http2StreamChannel Java Examples

The following examples show how to use io.netty.handler.codec.http2.Http2StreamChannel. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MultiplexedChannelRecord.java    From aws-sdk-java-v2 with Apache License 2.0 6 votes vote down vote up
/**
 * Handle a {@link Http2GoAwayFrame} on this connection, preventing new streams from being created on it, and closing any
 * streams newer than the last-stream-id on the go-away frame.
 */
void handleGoAway(int lastStreamId, GoAwayException exception) {
    doInEventLoop(connection.eventLoop(), () -> {
        this.lastStreamId = lastStreamId;

        if (state == RecordState.CLOSED) {
            return;
        }

        if (state == RecordState.OPEN) {
            state = RecordState.CLOSED_TO_NEW;
        }

        // Create a copy of the children to close, because fireExceptionCaught may remove from the childChannels.
        List<Http2StreamChannel> childrenToClose = new ArrayList<>(childChannels.values());
        childrenToClose.stream()
                       .filter(cc -> cc.stream().id() > lastStreamId)
                       .forEach(cc -> cc.pipeline().fireExceptionCaught(exception));
    });
}
 
Example #2
Source File: MultiplexedChannelRecord.java    From ambry with Apache License 2.0 6 votes vote down vote up
/**
 * Handle a {@link Http2GoAwayFrame} on this connection, preventing new streams from being created on it, and closing any
 * streams newer than the last-stream-id on the go-away frame. The GOAWAY frame (type=0x7) is used to initiate shutdown
 * of a connection or to signal serious error conditions. GOAWAY allows an endpoint to gracefully stop accepting new
 * streams while still finishing processing of previously established streams.
 * This enables administrative actions, like server maintenance.
 */
void handleGoAway(int lastStreamId, GoAwayException exception) {
  NettyUtils.doInEventLoop(parentChannel.eventLoop(), () -> {
    this.lastStreamId = lastStreamId;

    if (state == RecordState.CLOSED) {
      return;
    }

    if (state == RecordState.OPEN) {
      state = RecordState.CLOSED_TO_NEW;
    }

    // Create a copy of the children to close, because fireExceptionCaught may remove from the childChannels.
    List<Http2StreamChannel> childrenToClose = new ArrayList<>(streamChannels.values());
    childrenToClose.stream()
        .filter(cc -> cc.stream().id() > lastStreamId)
        .forEach(cc -> cc.pipeline().fireExceptionCaught(exception));
  });
}
 
Example #3
Source File: MultiplexedChannelRecord.java    From ambry with Apache License 2.0 6 votes vote down vote up
private void closeAndExecuteOnChildChannels(Consumer<Channel> childChannelConsumer) {
  NettyUtils.doInEventLoop(parentChannel.eventLoop(), () -> {
    if (state == RecordState.CLOSED) {
      return;
    }
    state = RecordState.CLOSED;

    // Create a copy of the children, because they may be modified by the consumer.
    List<Http2StreamChannel> childrenToClose = new ArrayList<>(streamChannels.values());
    for (Channel childChannel : childrenToClose) {
      childChannelConsumer.accept(childChannel);
      log.debug("fire exception to stream {} {} pipeline: {}. Active: {}", childChannel.hashCode(), childChannel,
          childChannel.pipeline(), childChannel.isOpen());
    }
  });
}
 
Example #4
Source File: MultiplexedChannelRecord.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
void acquireClaimedStream(Promise<Channel> promise) {
    doInEventLoop(connection.eventLoop(), () -> {
        if (state != RecordState.OPEN) {
            String message;
            // GOAWAY
            if (state == RecordState.CLOSED_TO_NEW) {
                message = String.format("Connection %s received GOAWAY with Last Stream ID %d. Unable to open new "
                                        + "streams on this connection.", connection, lastStreamId);
            } else {
                message = String.format("Connection %s was closed while acquiring new stream.", connection);
            }
            log.warn(() -> message);
            promise.setFailure(new IOException(message));
            return;
        }

        Future<Http2StreamChannel> streamFuture = new Http2StreamChannelBootstrap(connection).open();
        streamFuture.addListener((GenericFutureListener<Future<Http2StreamChannel>>) future -> {
            warnIfNotInEventLoop(connection.eventLoop());

            if (!future.isSuccess()) {
                promise.setFailure(future.cause());
                return;
            }

            Http2StreamChannel channel = future.getNow();
            channel.pipeline().addLast(UnusedChannelExceptionHandler.getInstance());
            childChannels.put(channel.id(), channel);
            promise.setSuccess(channel);

            if (closeIfIdleTask == null && allowedIdleConnectionTimeMillis != null) {
                enableCloseIfIdleTask();
            }
        });
    }, promise);
}
 
Example #5
Source File: MultiplexedChannelRecord.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
private void closeAndExecuteOnChildChannels(Consumer<Channel> childChannelConsumer) {
    doInEventLoop(connection.eventLoop(), () -> {
        if (state == RecordState.CLOSED) {
            return;
        }
        state = RecordState.CLOSED;

        // Create a copy of the children, because they may be modified by the consumer.
        List<Http2StreamChannel> childrenToClose = new ArrayList<>(childChannels.values());
        for (Channel childChannel : childrenToClose) {
            childChannelConsumer.accept(childChannel);
        }
    });
}
 
Example #6
Source File: Http2ConnectionProvider.java    From reactor-netty with Apache License 2.0 5 votes vote down vote up
@Override
public void operationComplete(Future<Http2StreamChannel> future) {
	Channel channel = pooledRef.poolable().channel();
	Http2FrameCodec frameCodec = channel.pipeline().get(Http2FrameCodec.class);
	if (future.isSuccess()) {
		Http2StreamChannel ch = future.getNow();

		if (!frameCodec.connection().local().canOpenStream()) {
			if (!retried) {
				if (log.isDebugEnabled()) {
					log.debug(format(ch, "Immediately aborted pooled channel max active streams is reached, " +
						"re-acquiring a new channel"));
				}
				pool.acquire(Duration.ofMillis(pendingAcquireTimeout))
				    .subscribe(new DisposableAcquire(this));
			}
			else {
				sink.error(new IOException("Error while acquiring from " + pool + ". Max active streams is reached."));
			}
		}
		else {
			ChannelOperations<?, ?> ops = ChannelOperations.get(ch);
			if (ops != null) {
				obs.onStateChange(ops, STREAM_CONFIGURED);
				sink.success(ops);
			}

			if (log.isDebugEnabled()) {
				log.debug(format(ch, "Stream opened, now {} active streams, {} max active streams."),
						frameCodec.connection().local().numActiveStreams(),
						frameCodec.connection().local().maxActiveStreams());
			}
		}
	}
	else {
		sink.error(future.cause());
	}

	release(this, channel);
}
 
Example #7
Source File: MultiplexedChannelRecord.java    From ambry with Apache License 2.0 5 votes vote down vote up
void acquireClaimedStream(Promise<Channel> promise) {
  NettyUtils.doInEventLoop(parentChannel.eventLoop(), () -> {
    if (state != RecordState.OPEN) {
      String message;
      // GOAWAY
      if (state == RecordState.CLOSED_TO_NEW) {
        message = String.format("Connection %s received GOAWAY with Last Stream ID %d. Unable to open new "
            + "streams on this connection.", parentChannel, lastStreamId);
      } else {
        message = String.format("Connection %s was closed while acquiring new stream.", parentChannel);
      }
      log.warn(message);
      promise.setFailure(new IOException(message));
      return;
    }

    Future<Http2StreamChannel> streamFuture =
        new Http2StreamChannelBootstrap(parentChannel).handler(streamChannelInitializer).open();
    streamFuture.addListener((GenericFutureListener<Future<Http2StreamChannel>>) future -> {
      NettyUtils.warnIfNotInEventLoop(parentChannel.eventLoop());

      if (!future.isSuccess()) {
        promise.setFailure(future.cause());
        return;
      }

      Http2StreamChannel channel = future.getNow();
      streamChannels.put(channel.id(), channel);
      promise.setSuccess(channel);

      if (closeIfIdleTask == null && allowedIdleTimeInMs != null && allowedIdleTimeInMs > 0) {
        enableCloseIfIdleTask();
      }
    });
  }, promise);
}
 
Example #8
Source File: Http2MultiplexedChannelPoolTest.java    From ambry with Apache License 2.0 5 votes vote down vote up
/**
 * Channel acquire and release test.
 */
@Test
public void streamChannelAcquireReleaseTest() throws Exception {
  Channel channel = newHttp2Channel();

  try {
    ChannelPool connectionPool = Mockito.mock(ChannelPool.class);

    loopGroup.register(channel).awaitUninterruptibly();
    Promise<Channel> channelPromise = new DefaultPromise<>(loopGroup.next());
    channelPromise.setSuccess(channel);

    Mockito.when(connectionPool.acquire()).thenReturn(channelPromise);

    Http2MultiplexedChannelPool h2Pool =
        new Http2MultiplexedChannelPool(connectionPool, loopGroup, new HashSet<>(), null,
            http2ClientConfigForOneConnection, new Http2ClientMetrics(new MetricRegistry()),
            streamChannelInitializer);

    Channel streamChannel1 = h2Pool.acquire().awaitUninterruptibly().getNow();
    assertTrue(streamChannel1 instanceof Http2StreamChannel);
    Mockito.verify(connectionPool, Mockito.times(1)).acquire();

    Channel streamChannel2 = h2Pool.acquire().awaitUninterruptibly().getNow();
    assertTrue(streamChannel2 instanceof Http2StreamChannel);
    Mockito.verify(connectionPool, Mockito.times(1)).acquire();

    // Verify number of numOfAvailableStreams
    MultiplexedChannelRecord multiplexedChannelRecord =
        streamChannel2.parent().attr(Http2MultiplexedChannelPool.MULTIPLEXED_CHANNEL).get();
    assertEquals(maxConcurrentStreamsPerConnection - 2, multiplexedChannelRecord.getNumOfAvailableStreams().get());
    h2Pool.release(streamChannel1).getNow();
    h2Pool.release(streamChannel2).getNow();
    assertEquals(maxConcurrentStreamsPerConnection, multiplexedChannelRecord.getNumOfAvailableStreams().get());
  } finally {
    channel.close();
  }
}
 
Example #9
Source File: HttpUtils.java    From zuul with Apache License 2.0 5 votes vote down vote up
public static Channel getMainChannel(Channel channel)
{
    if (channel instanceof Http2StreamChannel) {
        return channel.parent();
    }
    return channel;
}
 
Example #10
Source File: HttpClientConfig.java    From reactor-netty with Apache License 2.0 4 votes vote down vote up
static Future<Http2StreamChannel> openStream(Channel channel, ConnectionObserver observer, ChannelOperations.OnSetup opsFactory) {
	Http2StreamChannelBootstrap bootstrap = new Http2StreamChannelBootstrap(channel);
	bootstrap.option(ChannelOption.AUTO_READ, false);
	bootstrap.handler(new H2Codec(observer, opsFactory));
	return bootstrap.open();
}