-
Notifications
You must be signed in to change notification settings - Fork 4.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
router: set upstream host from the conn pool #33790
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,7 +82,8 @@ UpstreamRequest::UpstreamRequest(RouterFilterInterface& parent, | |
std::unique_ptr<GenericConnPool>&& conn_pool, | ||
bool can_send_early_data, bool can_use_http3, | ||
bool enable_half_close) | ||
: parent_(parent), conn_pool_(std::move(conn_pool)), | ||
: parent_(parent), conn_pool_(std::move(conn_pool)), upstream_host_(conn_pool_->host()), | ||
upstream_info_(std::make_shared<StreamInfo::UpstreamInfoImpl>()), | ||
stream_info_(parent_.callbacks()->dispatcher().timeSource(), nullptr, | ||
StreamInfo::FilterState::LifeSpan::FilterChain), | ||
start_time_(parent_.callbacks()->dispatcher().timeSource().monotonicTime()), | ||
|
@@ -110,14 +111,14 @@ UpstreamRequest::UpstreamRequest(RouterFilterInterface& parent, | |
} | ||
} | ||
|
||
// The router checks that the connection pool is non-null before creating the upstream request. | ||
auto upstream_host = conn_pool_->host(); | ||
// The router checks that the connection pool is non-null and valid before creating an | ||
// UpstreamRequest. | ||
ASSERT(upstream_host_ != nullptr, "Invalid connection pool"); | ||
upstream_info_->upstream_host_ = upstream_host_; | ||
|
||
Tracing::HttpTraceContext trace_context(*parent_.downstreamHeaders()); | ||
Tracing::UpstreamContext upstream_context(upstream_host.get(), // host_ | ||
&upstream_host->cluster(), // cluster_ | ||
Tracing::ServiceType::Unknown, // service_type_ | ||
false // async_client_span_ | ||
); | ||
Tracing::UpstreamContext upstream_context(upstream_host_.get(), &upstream_host_->cluster(), | ||
Tracing::ServiceType::Unknown, false); | ||
|
||
if (span_ != nullptr) { | ||
span_->injectContext(trace_context, upstream_context); | ||
|
@@ -128,9 +129,9 @@ UpstreamRequest::UpstreamRequest(RouterFilterInterface& parent, | |
parent_.callbacks()->activeSpan().injectContext(trace_context, upstream_context); | ||
} | ||
|
||
stream_info_.setUpstreamInfo(std::make_shared<StreamInfo::UpstreamInfoImpl>()); | ||
stream_info_.setUpstreamInfo(upstream_info_); | ||
stream_info_.route_ = parent_.callbacks()->route(); | ||
parent_.callbacks()->streamInfo().setUpstreamInfo(stream_info_.upstreamInfo()); | ||
parent_.callbacks()->streamInfo().setUpstreamInfo(upstream_info_); | ||
|
||
stream_info_.healthCheck(parent_.callbacks()->streamInfo().healthCheck()); | ||
stream_info_.setIsShadow(parent_.callbacks()->streamInfo().isShadow()); | ||
|
@@ -370,12 +371,21 @@ void UpstreamRequest::maybeEndDecode(bool end_stream) { | |
} | ||
} | ||
|
||
void UpstreamRequest::onUpstreamHostSelected(Upstream::HostDescriptionConstSharedPtr host, | ||
bool pool_success) { | ||
StreamInfo::UpstreamInfo& upstream_info = *streamInfo().upstreamInfo(); | ||
upstream_info.setUpstreamHost(host); | ||
upstream_host_ = host; | ||
parent_.onUpstreamHostSelected(host, pool_success); | ||
void UpstreamRequest::onUpstreamHostSelected(Upstream::HostDescriptionConstSharedPtr real_host, | ||
bool success) { | ||
// In most cases, the host description from host() of connection pool should be the same as | ||
// the host description from the connection pool callback. Exception is the logical host | ||
// which's addresses may be changed at runtime and the host description from the connection | ||
// pool callback will be different from the host description from host() of connection pool. | ||
if (real_host != nullptr && real_host != upstream_host_) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we're latching host early but it may change, can this be a problem for folks latched to the old version? Can you comment on why you want to latch early? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It is because the problem in our actually production scenario.
The real host may have different address with the early one. All other fields or content are same. If some one get the host after the upstream request is created and before the pool callbacks is called, the host may have different addresses with the final one. But I am open to this issue. It's would be great for me if we can figure out a better way to resolve above problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hah, may be can check if the upstream info has a valid upstream host when the upstream request is reset (remote or local), and if the upstream host is nullptr, we can get one from connection pool and set it to upstream info. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or is there a way of not snagging logical host? or subscribing to updates so it's always kept up to date, or actually grabbing the outer abstraction instead of a handle which can change? I think I'm OK with it changing if it must, but if we go that route we should probably also comment where the member is defined. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the logical host, when the connection is ready, the host will create a This is a way to ensure the finally However, with the support of the multiple-addresses of host, the correct way to get the accurate address of upstream host is the So, I doubt the value of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @alyssawilk There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this may need @mattklein123 - I'm not terribly familiar with the subtleties of realhostdescripton and local hosts |
||
upstream_host_ = std::move(real_host); | ||
upstream_info_->upstream_host_ = upstream_host_; | ||
} | ||
|
||
// Upstream host never be nullptr. The value may from the host() of connection pool or the | ||
// valid host description from the connection pool callback. | ||
ASSERT(upstream_host_ != nullptr); | ||
parent_.onUpstreamHostSelected(upstream_host_, success); | ||
} | ||
|
||
void UpstreamRequest::acceptHeadersFromRouter(bool end_stream) { | ||
|
@@ -574,7 +584,7 @@ void UpstreamRequest::onPoolFailure(ConnectionPool::PoolFailureReason reason, | |
stream_info_.upstreamInfo()->setUpstreamTransportFailureReason(transport_failure_reason); | ||
|
||
// Mimic an upstream reset. | ||
onUpstreamHostSelected(host, false); | ||
onUpstreamHostSelected(std::move(host), false); // Move host to the upstream_host_ if necessary. | ||
onResetStream(reset_reason, transport_failure_reason); | ||
} | ||
|
||
|
@@ -595,9 +605,8 @@ void UpstreamRequest::onPoolReady(std::unique_ptr<GenericUpstream>&& upstream, | |
upstream_->enableHalfClose(); | ||
} | ||
|
||
host->outlierDetector().putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess); | ||
|
||
onUpstreamHostSelected(host, true); | ||
onUpstreamHostSelected(std::move(host), true); // Move host to the upstream_host_ if necessary. | ||
upstream_host_->outlierDetector().putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess); | ||
|
||
if (protocol) { | ||
stream_info_.protocol(protocol.value()); | ||
|
@@ -668,8 +677,8 @@ void UpstreamRequest::onPoolReady(std::unique_ptr<GenericUpstream>&& upstream, | |
} | ||
|
||
const auto* route_entry = route().routeEntry(); | ||
if (route_entry->autoHostRewrite() && !host->hostname().empty()) { | ||
Http::Utility::updateAuthority(*parent_.downstreamHeaders(), host->hostname(), | ||
if (route_entry->autoHostRewrite() && !upstream_host_->hostname().empty()) { | ||
Http::Utility::updateAuthority(*parent_.downstreamHeaders(), upstream_host_->hostname(), | ||
route_entry->appendXfh()); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,7 +85,7 @@ class UpstreamRequest : public Logger::Loggable<Logger::Id::router>, | |
virtual void resetStream(); | ||
void setupPerTryTimeout(); | ||
void maybeEndDecode(bool end_stream); | ||
void onUpstreamHostSelected(Upstream::HostDescriptionConstSharedPtr host, bool pool_success); | ||
void onUpstreamHostSelected(Upstream::HostDescriptionConstSharedPtr real_host, bool success); | ||
|
||
// Http::StreamDecoder | ||
void decodeData(Buffer::Instance& data, bool end_stream) override; | ||
|
@@ -195,6 +195,7 @@ class UpstreamRequest : public Logger::Loggable<Logger::Id::router>, | |
std::unique_ptr<GenericUpstream> upstream_; | ||
absl::optional<Http::StreamResetReason> deferred_reset_reason_; | ||
Upstream::HostDescriptionConstSharedPtr upstream_host_; | ||
std::shared_ptr<StreamInfo::UpstreamInfoImpl> upstream_info_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we're going to eagerly create this, I think we can nix the local upsteam_host_ to not have it stored in many places. |
||
DownstreamWatermarkManager downstream_watermark_manager_{*this}; | ||
Tracing::SpanPtr span_; | ||
StreamInfo::StreamInfoImpl stream_info_; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why create this early but not set it early? Worth code comments I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR actually just set the upstream host early. The upstream info is still be created at the constructor (we just moved it more the constructor function to the constructor initialize list)?