private Future<?> doClose() {
    EventLoop closeEventLoop = eventLoopGroup.next();
    Promise<?> closeFinishedPromise = closeEventLoop.newPromise();

    NettyUtils.doInEventLoop(closeEventLoop, () -> {
      Promise<Void> releaseAllChannelsPromise = closeEventLoop.newPromise();
      PromiseCombiner promiseCombiner = new PromiseCombiner(closeEventLoop);

      // Create a copy of the connections to remove while we close them, in case closing updates the original list.
      List<MultiplexedChannelRecord> channelsToRemove = new ArrayList<>(parentConnections);
      for (MultiplexedChannelRecord channel : channelsToRemove) {
        promiseCombiner.add(closeAndReleaseParent(channel.getParentChannel()));
      }
      promiseCombiner.finish(releaseAllChannelsPromise);

      releaseAllChannelsPromise.addListener(f -> {
        parentConnectionPool.close();
        closeFinishedPromise.setSuccess(null);
      });
    });

    return closeFinishedPromise;
  }
Acquire a stream on a connection that has already been initialized. This will return false if the connection cannot have
any more streams allocated, and true if the stream can be allocated.

This will NEVER complete the provided future when the return value is false. This will ALWAYS complete the provided
future when the return value is true.
ambry-network/src/main/java/com/github/ambry/network/http2/Http2MultiplexedChannelPool.java