Skip to content
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

Refactor NullRouteImpl out of async client #28638

Merged
merged 4 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions source/common/http/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ envoy_package()

envoy_cc_library(
name = "async_client_lib",
srcs = ["async_client_impl.cc"],
hdrs = ["async_client_impl.h"],
srcs = [
"async_client_impl.cc",
],
hdrs = [
"async_client_impl.h",
],
deps = [
":null_route_impl_lib",
"//envoy/config:typed_metadata_interface",
"//envoy/event:dispatcher_interface",
"//envoy/http:async_client_interface",
Expand All @@ -23,14 +28,12 @@ envoy_cc_library(
"//envoy/http:header_map_interface",
"//envoy/http:message_interface",
"//envoy/router:context_interface",
"//envoy/router:router_interface",
"//envoy/router:router_ratelimit_interface",
"//envoy/router:shadow_writer_interface",
"//envoy/ssl:connection_interface",
"//envoy/stream_info:stream_info_interface",
"//source/common/common:empty_string",
"//source/common/common:linked_object",
"//source/common/router:router_lib",
"//source/common/stream_info:stream_info_lib",
"//source/common/tracing:http_tracer_lib",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
Expand All @@ -39,6 +42,17 @@ envoy_cc_library(
],
)

envoy_cc_library(
name = "null_route_impl_lib",
srcs = ["null_route_impl.cc"],
hdrs = ["null_route_impl.h"],
deps = [
":hash_policy_lib",
"//envoy/router:router_interface",
"//source/common/router:router_lib",
],
)

envoy_cc_library(
name = "async_client_utility_lib",
srcs = ["async_client_utility.cc"],
Expand Down
28 changes: 5 additions & 23 deletions source/common/http/async_client_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,18 @@

namespace Envoy {
namespace Http {

const std::vector<std::reference_wrapper<const Router::RateLimitPolicyEntry>>
AsyncStreamImpl::NullRateLimitPolicy::rate_limit_policy_entry_;
const AsyncStreamImpl::NullHedgePolicy AsyncStreamImpl::RouteEntryImpl::hedge_policy_;
const AsyncStreamImpl::NullRateLimitPolicy AsyncStreamImpl::RouteEntryImpl::rate_limit_policy_;
const Router::InternalRedirectPolicyImpl AsyncStreamImpl::RouteEntryImpl::internal_redirect_policy_;
const Router::PathMatcherSharedPtr AsyncStreamImpl::RouteEntryImpl::path_matcher_;
const Router::PathRewriterSharedPtr AsyncStreamImpl::RouteEntryImpl::path_rewriter_;
const std::vector<Router::ShadowPolicyPtr> AsyncStreamImpl::RouteEntryImpl::shadow_policies_;
const AsyncStreamImpl::NullVirtualHost AsyncStreamImpl::RouteEntryImpl::virtual_host_;
const AsyncStreamImpl::NullRateLimitPolicy AsyncStreamImpl::NullVirtualHost::rate_limit_policy_;
const AsyncStreamImpl::NullCommonConfig AsyncStreamImpl::NullVirtualHost::route_configuration_;
const std::multimap<std::string, std::string> AsyncStreamImpl::RouteEntryImpl::opaque_config_;
const AsyncStreamImpl::NullPathMatchCriterion
AsyncStreamImpl::RouteEntryImpl::path_match_criterion_;
const AsyncStreamImpl::RouteEntryImpl::ConnectConfigOptRef
AsyncStreamImpl::RouteEntryImpl::connect_config_nullopt_;
const std::list<LowerCaseString> AsyncStreamImpl::NullCommonConfig::internal_only_headers_;

AsyncClientImpl::AsyncClientImpl(Upstream::ClusterInfoConstSharedPtr cluster,
Stats::Store& stats_store, Event::Dispatcher& dispatcher,
const LocalInfo::LocalInfo& local_info,
Upstream::ClusterManager& cm, Runtime::Loader& runtime,
Random::RandomGenerator& random,
Router::ShadowWriterPtr&& shadow_writer,
Http::Context& http_context, Router::Context& router_context)
: cluster_(cluster),
: singleton_manager_(cm.clusterManagerFactory().singletonManager()), cluster_(cluster),
config_(http_context.asyncClientStatPrefix(), local_info, *stats_store.rootScope(), cm,
runtime, random, std::move(shadow_writer), true, false, false, false, false, false,
{}, dispatcher.timeSource(), http_context, router_context),
dispatcher_(dispatcher), singleton_manager_(cm.clusterManagerFactory().singletonManager()) {}
dispatcher_(dispatcher) {}

AsyncClientImpl::~AsyncClientImpl() {
while (!active_streams_.empty()) {
Expand Down Expand Up @@ -101,8 +82,9 @@ AsyncStreamImpl::AsyncStreamImpl(AsyncClientImpl& parent, AsyncClient::StreamCal
parent.config_.async_stats_),
stream_info_(Protocol::Http11, parent.dispatcher().timeSource(), nullptr),
tracing_config_(Tracing::EgressConfig::get()),
route_(std::make_shared<RouteImpl>(parent_, options.timeout, options.hash_policy,
options.retry_policy)),
route_(std::make_shared<NullRouteImpl>(parent_.cluster_->name(), parent_.singleton_manager_,
options.timeout, options.hash_policy,
options.retry_policy)),
account_(options.account_), buffer_limit_(options.buffer_limit_),
send_xff_(options.send_xff) {
stream_info_.dynamicMetadata().MergeFrom(options.metadata);
Expand Down
236 changes: 4 additions & 232 deletions source/common/http/async_client_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include "source/common/common/empty_string.h"
#include "source/common/common/linked_object.h"
#include "source/common/http/message_impl.h"
#include "source/common/protobuf/message_validator_impl.h"
#include "source/common/http/null_route_impl.h"
#include "source/common/router/config_impl.h"
#include "source/common/router/router.h"
#include "source/common/stream_info/stream_info_impl.h"
Expand Down Expand Up @@ -71,15 +71,15 @@ class AsyncClientImpl final : public AsyncClient {
Stream* start(StreamCallbacks& callbacks, const AsyncClient::StreamOptions& options) override;
OngoingRequest* startRequest(RequestHeaderMapPtr&& request_headers, Callbacks& callbacks,
const AsyncClient::RequestOptions& options) override;
Singleton::Manager& singleton_manager_;
Upstream::ClusterInfoConstSharedPtr cluster_;
Event::Dispatcher& dispatcher() override { return dispatcher_; }

private:
template <typename T> T* internalStartRequest(T* async_request);
Upstream::ClusterInfoConstSharedPtr cluster_;
Router::FilterConfig config_;
Event::Dispatcher& dispatcher_;
std::list<std::unique_ptr<AsyncStreamImpl>> active_streams_;
Singleton::Manager& singleton_manager_;

friend class AsyncStreamImpl;
friend class AsyncRequestSharedImpl;
Expand Down Expand Up @@ -153,234 +153,6 @@ class AsyncStreamImpl : public virtual AsyncClient::Stream,
absl::optional<std::reference_wrapper<DecoderFilterWatermarkCallbacks>> watermark_callbacks_;

private:
struct NullHedgePolicy : public Router::HedgePolicy {
// Router::HedgePolicy
uint32_t initialRequests() const override { return 1; }
const envoy::type::v3::FractionalPercent& additionalRequestChance() const override {
return additional_request_chance_;
}
bool hedgeOnPerTryTimeout() const override { return false; }

const envoy::type::v3::FractionalPercent additional_request_chance_;
};

struct NullRateLimitPolicy : public Router::RateLimitPolicy {
// Router::RateLimitPolicy
const std::vector<std::reference_wrapper<const Router::RateLimitPolicyEntry>>&
getApplicableRateLimit(uint64_t) const override {
return rate_limit_policy_entry_;
}
bool empty() const override { return true; }

static const std::vector<std::reference_wrapper<const Router::RateLimitPolicyEntry>>
rate_limit_policy_entry_;
};

struct NullCommonConfig : public Router::CommonConfig {
const std::list<LowerCaseString>& internalOnlyHeaders() const override {
return internal_only_headers_;
}

const std::string& name() const override { return EMPTY_STRING; }
bool usesVhds() const override { return false; }
bool mostSpecificHeaderMutationsWins() const override { return false; }
uint32_t maxDirectResponseBodySizeBytes() const override { return 0; }

static const std::list<LowerCaseString> internal_only_headers_;
};

struct NullVirtualHost : public Router::VirtualHost {
// Router::VirtualHost
Stats::StatName statName() const override { return {}; }
const Router::RateLimitPolicy& rateLimitPolicy() const override { return rate_limit_policy_; }
const Router::CorsPolicy* corsPolicy() const override { return nullptr; }
const Router::CommonConfig& routeConfig() const override { return route_configuration_; }
bool includeAttemptCountInRequest() const override { return false; }
bool includeAttemptCountInResponse() const override { return false; }
bool includeIsTimeoutRetryHeader() const override { return false; }
uint32_t retryShadowBufferLimit() const override {
return std::numeric_limits<uint32_t>::max();
}
const Router::RouteSpecificFilterConfig*
mostSpecificPerFilterConfig(const std::string&) const override {
return nullptr;
}
void traversePerFilterConfig(
const std::string&,
std::function<void(const Router::RouteSpecificFilterConfig&)>) const override {}
static const NullRateLimitPolicy rate_limit_policy_;
static const NullCommonConfig route_configuration_;
};

struct NullPathMatchCriterion : public Router::PathMatchCriterion {
Router::PathMatchType matchType() const override { return Router::PathMatchType::None; }
const std::string& matcher() const override { return EMPTY_STRING; }
};

struct RouteEntryImpl : public Router::RouteEntry {
RouteEntryImpl(
AsyncClientImpl& parent, const absl::optional<std::chrono::milliseconds>& timeout,
const Protobuf::RepeatedPtrField<envoy::config::route::v3::RouteAction::HashPolicy>&
hash_policy,
const absl::optional<envoy::config::route::v3::RetryPolicy>& retry_policy)
: cluster_name_(parent.cluster_->name()), timeout_(timeout) {
if (!hash_policy.empty()) {
hash_policy_ = std::make_unique<HashPolicyImpl>(hash_policy);
}
if (retry_policy.has_value()) {
// ProtobufMessage::getStrictValidationVisitor() ? how often do we do this?
Upstream::RetryExtensionFactoryContextImpl factory_context(parent.singleton_manager_);
retry_policy_ = std::make_unique<Router::RetryPolicyImpl>(
retry_policy.value(), ProtobufMessage::getNullValidationVisitor(), factory_context);
} else {
retry_policy_ = std::make_unique<Router::RetryPolicyImpl>();
}
}

// Router::RouteEntry
const std::string& clusterName() const override { return cluster_name_; }
const Router::RouteStatsContextOptRef routeStatsContext() const override {
return Router::RouteStatsContextOptRef();
}
Http::Code clusterNotFoundResponseCode() const override {
return Http::Code::InternalServerError;
}
const Router::CorsPolicy* corsPolicy() const override { return nullptr; }
absl::optional<std::string>
currentUrlPathAfterRewrite(const Http::RequestHeaderMap&) const override {
return {};
}
void finalizeRequestHeaders(Http::RequestHeaderMap&, const StreamInfo::StreamInfo&,
bool) const override {}
Http::HeaderTransforms requestHeaderTransforms(const StreamInfo::StreamInfo&,
bool) const override {
return {};
}
void finalizeResponseHeaders(Http::ResponseHeaderMap&,
const StreamInfo::StreamInfo&) const override {}
Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo&,
bool) const override {
return {};
}
const HashPolicy* hashPolicy() const override { return hash_policy_.get(); }
const Router::HedgePolicy& hedgePolicy() const override { return hedge_policy_; }
const Router::MetadataMatchCriteria* metadataMatchCriteria() const override { return nullptr; }
Upstream::ResourcePriority priority() const override {
return Upstream::ResourcePriority::Default;
}
const Router::RateLimitPolicy& rateLimitPolicy() const override { return rate_limit_policy_; }
const Router::RetryPolicy& retryPolicy() const override { return *retry_policy_; }
const Router::InternalRedirectPolicy& internalRedirectPolicy() const override {
return internal_redirect_policy_;
}
const Router::PathMatcherSharedPtr& pathMatcher() const override { return path_matcher_; }
const Router::PathRewriterSharedPtr& pathRewriter() const override { return path_rewriter_; }
uint32_t retryShadowBufferLimit() const override {
return std::numeric_limits<uint32_t>::max();
}
const std::vector<Router::ShadowPolicyPtr>& shadowPolicies() const override {
return shadow_policies_;
}
std::chrono::milliseconds timeout() const override {
if (timeout_) {
return timeout_.value();
} else {
return std::chrono::milliseconds(0);
}
}
bool usingNewTimeouts() const override { return false; }
absl::optional<std::chrono::milliseconds> idleTimeout() const override { return absl::nullopt; }
absl::optional<std::chrono::milliseconds> maxStreamDuration() const override {
return absl::nullopt;
}
absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderMax() const override {
return absl::nullopt;
}
absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderOffset() const override {
return absl::nullopt;
}
absl::optional<std::chrono::milliseconds> maxGrpcTimeout() const override {
return absl::nullopt;
}
absl::optional<std::chrono::milliseconds> grpcTimeoutOffset() const override {
return absl::nullopt;
}
const Router::VirtualCluster* virtualCluster(const Http::HeaderMap&) const override {
return nullptr;
}
const Router::TlsContextMatchCriteria* tlsContextMatchCriteria() const override {
return nullptr;
}
const std::multimap<std::string, std::string>& opaqueConfig() const override {
return opaque_config_;
}
const Router::VirtualHost& virtualHost() const override { return virtual_host_; }
bool autoHostRewrite() const override { return false; }
bool appendXfh() const override { return false; }
bool includeVirtualHostRateLimits() const override { return true; }
const Router::PathMatchCriterion& pathMatchCriterion() const override {
return path_match_criterion_;
}

const ConnectConfigOptRef connectConfig() const override { return connect_config_nullopt_; }

bool includeAttemptCountInRequest() const override { return false; }
bool includeAttemptCountInResponse() const override { return false; }
const Router::RouteEntry::UpgradeMap& upgradeMap() const override { return upgrade_map_; }
const std::string& routeName() const override { return route_name_; }
const Router::EarlyDataPolicy& earlyDataPolicy() const override { return *early_data_policy_; }

std::unique_ptr<const HashPolicyImpl> hash_policy_;
std::unique_ptr<Router::RetryPolicy> retry_policy_;

static const NullHedgePolicy hedge_policy_;
static const NullRateLimitPolicy rate_limit_policy_;
static const Router::InternalRedirectPolicyImpl internal_redirect_policy_;
static const Router::PathMatcherSharedPtr path_matcher_;
static const Router::PathRewriterSharedPtr path_rewriter_;
static const std::vector<Router::ShadowPolicyPtr> shadow_policies_;
static const NullVirtualHost virtual_host_;
static const std::multimap<std::string, std::string> opaque_config_;
static const NullPathMatchCriterion path_match_criterion_;

Router::RouteEntry::UpgradeMap upgrade_map_;
const std::string& cluster_name_;
absl::optional<std::chrono::milliseconds> timeout_;
static const ConnectConfigOptRef connect_config_nullopt_;
const std::string route_name_;
// Pass early data option config through StreamOptions.
std::unique_ptr<Router::EarlyDataPolicy> early_data_policy_{
new Router::DefaultEarlyDataPolicy(true)};
};

struct RouteImpl : public Router::Route {
RouteImpl(AsyncClientImpl& parent, const absl::optional<std::chrono::milliseconds>& timeout,
const Protobuf::RepeatedPtrField<envoy::config::route::v3::RouteAction::HashPolicy>&
hash_policy,
const absl::optional<envoy::config::route::v3::RetryPolicy>& retry_policy)
: route_entry_(parent, timeout, hash_policy, retry_policy), typed_metadata_({}) {}

// Router::Route
const Router::DirectResponseEntry* directResponseEntry() const override { return nullptr; }
const Router::RouteEntry* routeEntry() const override { return &route_entry_; }
const Router::Decorator* decorator() const override { return nullptr; }
const Router::RouteTracing* tracingConfig() const override { return nullptr; }
const Router::RouteSpecificFilterConfig*
mostSpecificPerFilterConfig(const std::string&) const override {
return nullptr;
}
void traversePerFilterConfig(
const std::string&,
std::function<void(const Router::RouteSpecificFilterConfig&)>) const override {}
const envoy::config::core::v3::Metadata& metadata() const override { return metadata_; }
const Envoy::Config::TypedMetadata& typedMetadata() const override { return typed_metadata_; }
bool filterDisabled(absl::string_view) const override { return false; }

RouteEntryImpl route_entry_;
const envoy::config::core::v3::Metadata metadata_;
const Envoy::Config::TypedMetadataImpl<Envoy::Config::TypedMetadataFactory> typed_metadata_;
};

void cleanup();
void closeRemote(bool end_stream);
bool complete() { return local_closed_ && remote_closed_; }
Expand Down Expand Up @@ -496,7 +268,7 @@ class AsyncStreamImpl : public virtual AsyncClient::Stream,
StreamInfo::StreamInfoImpl stream_info_;
Tracing::NullSpan active_span_;
const Tracing::Config& tracing_config_;
std::shared_ptr<RouteImpl> route_;
std::shared_ptr<NullRouteImpl> route_;
uint32_t high_watermark_calls_{};
bool local_closed_{};
bool remote_closed_{};
Expand Down
23 changes: 23 additions & 0 deletions source/common/http/null_route_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "null_route_impl.h"

#include <vector>

namespace Envoy {
namespace Http {
const std::vector<std::reference_wrapper<const Router::RateLimitPolicyEntry>>
NullRateLimitPolicy::rate_limit_policy_entry_;
const NullHedgePolicy RouteEntryImpl::hedge_policy_;
const NullRateLimitPolicy RouteEntryImpl::rate_limit_policy_;
const Router::InternalRedirectPolicyImpl RouteEntryImpl::internal_redirect_policy_;
const Router::PathMatcherSharedPtr RouteEntryImpl::path_matcher_;
const Router::PathRewriterSharedPtr RouteEntryImpl::path_rewriter_;
const std::vector<Router::ShadowPolicyPtr> RouteEntryImpl::shadow_policies_;
const NullVirtualHost RouteEntryImpl::virtual_host_;
const NullRateLimitPolicy NullVirtualHost::rate_limit_policy_;
const NullCommonConfig NullVirtualHost::route_configuration_;
const std::multimap<std::string, std::string> RouteEntryImpl::opaque_config_;
const NullPathMatchCriterion RouteEntryImpl::path_match_criterion_;
const RouteEntryImpl::ConnectConfigOptRef RouteEntryImpl::connect_config_nullopt_;
const std::list<LowerCaseString> NullCommonConfig::internal_only_headers_;
} // namespace Http
} // namespace Envoy
Loading
Loading