diff --git a/source/common/http/http2/conn_pool.cc b/source/common/http/http2/conn_pool.cc index d83def2ec18ea..70b9ee71b976c 100644 --- a/source/common/http/http2/conn_pool.cc +++ b/source/common/http/http2/conn_pool.cc @@ -12,6 +12,10 @@ namespace Envoy { namespace Http { namespace Http2 { +// All streams are 2^31. Client streams are half that, minus stream 0. Just to be on the safe +// side we do 2^29. +static const uint64_t DEFAULT_MAX_STREAMS = (1 << 29); + ConnPoolImpl::ConnPoolImpl(Event::Dispatcher& dispatcher, Random::RandomGenerator& random_generator, Upstream::HostConstSharedPtr host, Upstream::ResourcePriority priority, const Network::ConnectionSocket::OptionsSharedPtr& options, @@ -25,54 +29,53 @@ ConnPoolImpl::~ConnPoolImpl() { destructAllConnections(); } Envoy::ConnectionPool::ActiveClientPtr ConnPoolImpl::instantiateActiveClient() { return std::make_unique(*this); } -void ConnPoolImpl::onGoAway(ActiveClient& client, Http::GoAwayErrorCode) { - ENVOY_CONN_LOG(debug, "remote goaway", *client.codec_client_); - host_->cluster().stats().upstream_cx_close_notify_.inc(); - if (client.state_ != ActiveClient::State::DRAINING) { - if (client.codec_client_->numActiveRequests() == 0) { - client.codec_client_->close(); + +void ConnPoolImpl::ActiveClient::onGoAway(Http::GoAwayErrorCode) { + ENVOY_CONN_LOG(debug, "remote goaway", *codec_client_); + parent_.host()->cluster().stats().upstream_cx_close_notify_.inc(); + if (state_ != ActiveClient::State::DRAINING) { + if (codec_client_->numActiveRequests() == 0) { + codec_client_->close(); } else { - transitionActiveClientState(client, ActiveClient::State::DRAINING); + parent_.transitionActiveClientState(*this, ActiveClient::State::DRAINING); } } } -void ConnPoolImpl::onStreamDestroy(ActiveClient& client) { - onStreamClosed(client, false); +void ConnPoolImpl::ActiveClient::onStreamDestroy() { + parent().onStreamClosed(*this, false); // If we are destroying this stream because of a disconnect, do not check for drain here. We will // wait until the connection has been fully drained of streams and then check in the connection // event callback. - if (!client.closed_with_active_rq_) { - checkForDrained(); + if (!closed_with_active_rq_) { + parent().checkForDrained(); } } -void ConnPoolImpl::onStreamReset(ActiveClient& client, Http::StreamResetReason reason) { +void ConnPoolImpl::ActiveClient::onStreamReset(Http::StreamResetReason reason) { if (reason == StreamResetReason::ConnectionTermination || reason == StreamResetReason::ConnectionFailure) { - host_->cluster().stats().upstream_rq_pending_failure_eject_.inc(); - client.closed_with_active_rq_ = true; + parent_.host()->cluster().stats().upstream_rq_pending_failure_eject_.inc(); + closed_with_active_rq_ = true; } else if (reason == StreamResetReason::LocalReset) { - host_->cluster().stats().upstream_rq_tx_reset_.inc(); + parent_.host()->cluster().stats().upstream_rq_tx_reset_.inc(); } else if (reason == StreamResetReason::RemoteReset) { - host_->cluster().stats().upstream_rq_rx_reset_.inc(); + parent_.host()->cluster().stats().upstream_rq_rx_reset_.inc(); } } -uint64_t ConnPoolImpl::maxStreamsPerConnection() { - uint64_t max_streams_config = host_->cluster().maxRequestsPerConnection(); +uint64_t maxStreamsPerConnection(uint64_t max_streams_config) { return (max_streams_config != 0) ? max_streams_config : DEFAULT_MAX_STREAMS; } -ConnPoolImpl::ActiveClient::ActiveClient(ConnPoolImpl& parent) +ConnPoolImpl::ActiveClient::ActiveClient(Envoy::Http::HttpConnPoolImplBase& parent) : Envoy::Http::ActiveClient( - parent, parent.maxStreamsPerConnection(), - parent.host_->cluster().http2Options().max_concurrent_streams().value()) { + parent, maxStreamsPerConnection(parent.host()->cluster().maxRequestsPerConnection()), + parent.host()->cluster().http2Options().max_concurrent_streams().value()) { codec_client_->setCodecClientCallbacks(*this); codec_client_->setCodecConnectionCallbacks(*this); - - parent.host_->cluster().stats().upstream_cx_http2_total_.inc(); + parent.host()->cluster().stats().upstream_cx_http2_total_.inc(); } bool ConnPoolImpl::ActiveClient::closingWithIncompleteStream() const { diff --git a/source/common/http/http2/conn_pool.h b/source/common/http/http2/conn_pool.h index 63aabe08e2a58..85b5c39497527 100644 --- a/source/common/http/http2/conn_pool.h +++ b/source/common/http/http2/conn_pool.h @@ -31,12 +31,13 @@ class ConnPoolImpl : public Envoy::Http::HttpConnPoolImplBase { // ConnPoolImplBase Envoy::ConnectionPool::ActiveClientPtr instantiateActiveClient() override; -protected: class ActiveClient : public CodecClientCallbacks, public Http::ConnectionCallbacks, public Envoy::Http::ActiveClient { public: - ActiveClient(ConnPoolImpl& parent); + ActiveClient(Envoy::Http::HttpConnPoolImplBase& parent); + ActiveClient(Envoy::Http::HttpConnPoolImplBase& parent, + Upstream::Host::CreateConnectionData& data); ~ActiveClient() override = default; ConnPoolImpl& parent() { return static_cast(parent_); } @@ -46,29 +47,15 @@ class ConnPoolImpl : public Envoy::Http::HttpConnPoolImplBase { RequestEncoder& newStreamEncoder(ResponseDecoder& response_decoder) override; // CodecClientCallbacks - void onStreamDestroy() override { parent().onStreamDestroy(*this); } - void onStreamReset(Http::StreamResetReason reason) override { - parent().onStreamReset(*this, reason); - } + void onStreamDestroy() override; + void onStreamReset(Http::StreamResetReason reason) override; // Http::ConnectionCallbacks - void onGoAway(Http::GoAwayErrorCode error_code) override { - parent().onGoAway(*this, error_code); - } + void onGoAway(Http::GoAwayErrorCode error_code) override; bool closed_with_active_rq_{}; }; - uint64_t maxStreamsPerConnection(); - void movePrimaryClientToDraining(); - void onGoAway(ActiveClient& client, Http::GoAwayErrorCode error_code); - void onStreamDestroy(ActiveClient& client); - void onStreamReset(ActiveClient& client, Http::StreamResetReason reason); - - // All streams are 2^31. Client streams are half that, minus stream 0. Just to be on the safe - // side we do 2^29. - static const uint64_t DEFAULT_MAX_STREAMS = (1 << 29); - Random::RandomGenerator& random_generator_; };