Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7b3bfc9
replace FactoryContext with ServerFactoryContext in router/... so tha…
stevenzzzz Jan 22, 2020
e8de6c1
fix feedbacks
stevenzzzz Jan 27, 2020
64757d1
if only we can turn up spelling check at local
stevenzzzz Jan 27, 2020
17570bc
merge with master
stevenzzzz Jan 28, 2020
282a4c9
fix typo introduced during merging w/master
stevenzzzz Jan 28, 2020
71842d5
move local-init-manager to config-provider framework
stevenzzzz Jan 31, 2020
2c4b342
merge upstream master
stevenzzzz Feb 3, 2020
86799d4
fixes per review feedbacks
stevenzzzz Feb 7, 2020
7fd6fbe
add back the missing listenerimpl destructor, of course I have 4 back…
stevenzzzz Feb 7, 2020
2ba3f96
Merge branch 'master' into final-look-longlive-srds
stevenzzzz Feb 11, 2020
f01dc42
add a test for listener_impl destructor notifying parent initManager
stevenzzzz Feb 13, 2020
81c9fee
fix wrong parameter comment
stevenzzzz Feb 13, 2020
e13189e
fix accidental typo
stevenzzzz Feb 14, 2020
e7c567a
Merge branch 'master' into final-look-longlive-srds
stevenzzzz Feb 14, 2020
3a39741
fix one typo at a time
stevenzzzz Feb 14, 2020
78cb57d
add a integration test for listener + LDS
stevenzzzz Feb 28, 2020
2dadf40
merge from master
stevenzzzz Feb 28, 2020
7f7786f
some comment update on integration test
stevenzzzz Feb 28, 2020
ebd5d3d
fix format and typo
stevenzzzz Feb 28, 2020
65eb728
fix typo, one at a time
stevenzzzz Mar 2, 2020
8145447
Merge branch 'master' of https://github.com/envoyproxy/envoy into fin…
stevenzzzz Mar 2, 2020
d1204f1
make type more specific
stevenzzzz Mar 2, 2020
b08bded
fix compilation error
stevenzzzz Mar 3, 2020
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
10 changes: 6 additions & 4 deletions include/envoy/config/config_provider_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class ConfigProviderManager {
* and Config are shared amongst all providers relying on the same config source.
* @param config_source_proto supplies the proto containing the xDS API configuration.
* @param factory_context is the context to use for the provider.
* @param init_manager is the Init::Manager to use for the provider.
* @param stat_prefix supplies the prefix to use for statistics.
* @param optarg supplies an optional argument with data specific to the concrete class.
* @return ConfigProviderPtr a newly allocated dynamic config provider which shares underlying
Expand All @@ -52,8 +53,9 @@ class ConfigProviderManager {
*/
virtual ConfigProviderPtr
createXdsConfigProvider(const Protobuf::Message& config_source_proto,
Server::Configuration::FactoryContext& factory_context,
const std::string& stat_prefix, const OptionalArg& optarg) PURE;
Server::Configuration::ServerFactoryContext& factory_context,
Init::Manager& init_manager, const std::string& stat_prefix,
const OptionalArg& optarg) PURE;

/**
* Returns a ConfigProvider associated with a statically specified configuration.
Expand All @@ -64,7 +66,7 @@ class ConfigProviderManager {
*/
virtual ConfigProviderPtr
createStaticConfigProvider(const Protobuf::Message& config_proto,
Server::Configuration::FactoryContext& factory_context,
Server::Configuration::ServerFactoryContext& factory_context,
const OptionalArg& optarg) {
UNREFERENCED_PARAMETER(config_proto);
UNREFERENCED_PARAMETER(factory_context);
Expand All @@ -82,7 +84,7 @@ class ConfigProviderManager {
*/
virtual ConfigProviderPtr
createStaticConfigProvider(ProtobufTypes::ConstMessagePtrVector&& config_protos,
Server::Configuration::FactoryContext& factory_context,
Server::Configuration::ServerFactoryContext& factory_context,
const OptionalArg& optarg) {
UNREFERENCED_PARAMETER(config_protos);
UNREFERENCED_PARAMETER(factory_context);
Expand Down
8 changes: 4 additions & 4 deletions include/envoy/router/route_config_provider_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class RouteConfigProviderManager {
*/
virtual RouteConfigProviderSharedPtr createRdsRouteConfigProvider(
const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds,
Server::Configuration::FactoryContext& factory_context, const std::string& stat_prefix,
Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix,
Init::Manager& init_manager) PURE;

/**
Expand All @@ -49,9 +49,9 @@ class RouteConfigProviderManager {
* @param runtime supplies the runtime loader.
* @param cm supplies the ClusterManager.
*/
virtual RouteConfigProviderPtr
createStaticRouteConfigProvider(const envoy::config::route::v3::RouteConfiguration& route_config,
Server::Configuration::FactoryContext& factory_context) PURE;
virtual RouteConfigProviderPtr createStaticRouteConfigProvider(
const envoy::config::route::v3::RouteConfiguration& route_config,
Server::Configuration::ServerFactoryContext& factory_context) PURE;
};

} // namespace Router
Expand Down
6 changes: 6 additions & 0 deletions include/envoy/server/filter_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ class CommonFactoryContext {
*/
virtual const LocalInfo::LocalInfo& localInfo() const PURE;

/**
* @return ProtobufMessage::ValidationContext& validation visitor for xDS&static configuration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @return ProtobufMessage::ValidationContext& validation visitor for xDS&static configuration
* @return ProtobufMessage::ValidationContext& validation visitor for xDS and static configuration

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* messages.
*/
virtual ProtobufMessage::ValidationContext& messageValidationContext() PURE;

/**
* @return RandomGenerator& the random generator for the server.
*/
Expand Down
3 changes: 2 additions & 1 deletion source/common/config/config_provider_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Envoy {
namespace Config {

ImmutableConfigProviderBase::ImmutableConfigProviderBase(
Server::Configuration::FactoryContext& factory_context,
Server::Configuration::ServerFactoryContext& factory_context,
ConfigProviderManagerImplBase& config_provider_manager,
ConfigProviderInstanceType instance_type, ApiType api_type)
: last_updated_(factory_context.timeSource().systemTime()),
Expand All @@ -21,6 +21,7 @@ ImmutableConfigProviderBase::~ImmutableConfigProviderBase() {

ConfigSubscriptionCommonBase::~ConfigSubscriptionCommonBase() {
init_target_.ready();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please avoid gratuitous whitespace changes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

config_provider_manager_.unbindSubscription(manager_identifier_);
}

Expand Down
12 changes: 3 additions & 9 deletions source/common/config/config_provider_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class ImmutableConfigProviderBase : public ConfigProvider {
ConfigProviderInstanceType instanceType() const { return instance_type_; }

protected:
ImmutableConfigProviderBase(Server::Configuration::FactoryContext& factory_context,
ImmutableConfigProviderBase(Server::Configuration::ServerFactoryContext& factory_context,
ConfigProviderManagerImplBase& config_provider_manager,
ConfigProviderInstanceType instance_type, ApiType api_type);

Expand All @@ -137,12 +137,6 @@ class MutableConfigProviderCommonBase;
* A subscription is intended to be co-owned by config providers with the same config source, it's
* designed to be created/destructed on admin thread only.
*
* xDS config providers and subscriptions are split to avoid lifetime issues with arguments
* required by the config providers. An example is the Server::Configuration::FactoryContext, which
* is owned by listeners and therefore may be destroyed while an associated config provider is still
* in use (see #3960). This split enables single ownership of the config providers, while enabling
* shared ownership of the underlying subscription.
*
*/
class ConfigSubscriptionCommonBase : protected Logger::Loggable<Logger::Id::config> {
public:
Expand Down Expand Up @@ -202,7 +196,7 @@ class ConfigSubscriptionCommonBase : protected Logger::Loggable<Logger::Id::conf

ConfigSubscriptionCommonBase(const std::string& name, const uint64_t manager_identifier,
ConfigProviderManagerImplBase& config_provider_manager,
Server::Configuration::FactoryContext& factory_context)
Server::Configuration::ServerFactoryContext& factory_context)
: name_(name), tls_(factory_context.threadLocal().allocateSlot()),
init_target_(absl::StrCat("ConfigSubscriptionCommonBase ", name_), [this]() { start(); }),
manager_identifier_(manager_identifier), config_provider_manager_(config_provider_manager),
Expand Down Expand Up @@ -259,7 +253,7 @@ class ConfigSubscriptionInstance : public ConfigSubscriptionCommonBase {
public:
ConfigSubscriptionInstance(const std::string& name, const uint64_t manager_identifier,
ConfigProviderManagerImplBase& config_provider_manager,
Server::Configuration::FactoryContext& factory_context)
Server::Configuration::ServerFactoryContext& factory_context)
: ConfigSubscriptionCommonBase(name, manager_identifier, config_provider_manager,
factory_context) {}

Expand Down
68 changes: 36 additions & 32 deletions source/common/router/rds_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ namespace Router {
RouteConfigProviderSharedPtr RouteConfigProviderUtil::create(
const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
config,
Server::Configuration::FactoryContext& factory_context, const std::string& stat_prefix,
RouteConfigProviderManager& route_config_provider_manager) {
Server::Configuration::ServerFactoryContext& factory_context, Init::Manager& init_manager,
const std::string& stat_prefix, RouteConfigProviderManager& route_config_provider_manager) {
switch (config.route_specifier_case()) {
case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager::
RouteSpecifierCase::kRouteConfig:
Expand All @@ -38,18 +38,21 @@ RouteConfigProviderSharedPtr RouteConfigProviderUtil::create(
case envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager::
RouteSpecifierCase::kRds:
return route_config_provider_manager.createRdsRouteConfigProvider(
config.rds(), factory_context, stat_prefix, factory_context.initManager());
// At the creation of a RDS route config provider, the factory_context's initManager is
// always valid, though the init manager may go away later when the listener goes away.
config.rds(), factory_context, stat_prefix, init_manager);
default:
NOT_REACHED_GCOVR_EXCL_LINE;
}
}

StaticRouteConfigProviderImpl::StaticRouteConfigProviderImpl(
const envoy::config::route::v3::RouteConfiguration& config,
Server::Configuration::FactoryContext& factory_context,
Server::Configuration::ServerFactoryContext& factory_context,
RouteConfigProviderManagerImpl& route_config_provider_manager)
: config_(new ConfigImpl(config, factory_context.getServerFactoryContext(),
factory_context.messageValidationVisitor(), true)),
: config_(new ConfigImpl(config, factory_context,
factory_context.messageValidationContext().staticValidationVisitor(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this still might not be correct; what if you have an inline route in an HCM that is delivered via a Listener in a LDS message? The validation should be dynamic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert it. This PR is supposed to be a child PR of #9621.

But we can also work on this PR to solve the problem in one shot. :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we don't want FactoryContext to contain a messageValidationVisitor() method, I can do another cleanup PR which will pipe the validator from ListenerImpl --> ... --> HCM::Config.

true)),

route_config_proto_{config}, last_updated_(factory_context.timeSource().systemTime()),
route_config_provider_manager_(route_config_provider_manager) {
Expand All @@ -64,13 +67,18 @@ StaticRouteConfigProviderImpl::~StaticRouteConfigProviderImpl() {
RdsRouteConfigSubscription::RdsRouteConfigSubscription(
const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds,
const uint64_t manager_identifier, Server::Configuration::ServerFactoryContext& factory_context,
ProtobufMessage::ValidationVisitor& validator, Init::Manager& init_manager,
const std::string& stat_prefix,
Envoy::Router::RouteConfigProviderManagerImpl& route_config_provider_manager)
: route_config_name_(rds.route_config_name()), factory_context_(factory_context),
validator_(validator), init_manager_(init_manager),
init_target_(fmt::format("RdsRouteConfigSubscription {}", route_config_name_),
[this]() { subscription_->start({route_config_name_}); }),
validator_(factory_context.messageValidationContext().dynamicValidationVisitor()),
parent_init_target_(fmt::format("RdsRouteConfigSubscription init {}", route_config_name_),
[this]() { local_init_manager_.initialize(init_watcher_); }),
init_watcher_(fmt::format("RDS local-init-watcher {}", rds.route_config_name()),
[this]() { parent_init_target_.ready(); }),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me and is roughly how I was envisaging transitive init managers working. @mergeconflict @lambdai did you have any thoughts here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Based on my understanding this field initialization order doesn't introduce initialized-after-detroy

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine, if it's needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

local_init_target_(
fmt::format("RdsRouteConfigSubscription local-init-target {}", route_config_name_),
[this]() { subscription_->start({route_config_name_}); }),
local_init_manager_(fmt::format("RDS local-init-manager {}", route_config_name_)),
scope_(factory_context.scope().createScope(stat_prefix + "rds." + route_config_name_ + ".")),
stat_prefix_(stat_prefix), stats_({ALL_RDS_STATS(POOL_COUNTER(*scope_))}),
route_config_provider_manager_(route_config_provider_manager),
Expand All @@ -80,13 +88,14 @@ RdsRouteConfigSubscription::RdsRouteConfigSubscription(
factory_context.clusterManager().subscriptionFactory().subscriptionFromConfigSource(
rds.config_source(), loadTypeUrl(rds.config_source().resource_api_version()), *scope_,
*this);
local_init_manager_.add(local_init_target_);
config_update_info_ =
std::make_unique<RouteConfigUpdateReceiverImpl>(factory_context.timeSource(), validator);
std::make_unique<RouteConfigUpdateReceiverImpl>(factory_context.timeSource(), validator_);
}

RdsRouteConfigSubscription::~RdsRouteConfigSubscription() {
// If we get destroyed during initialization, make sure we signal that we "initialized".
init_target_.ready();
local_init_target_.ready();

// The ownership of RdsRouteConfigProviderImpl is shared among all HttpConnectionManagers that
// hold a shared_ptr to it. The RouteConfigProviderManager holds weak_ptrs to the
Expand All @@ -113,12 +122,10 @@ void RdsRouteConfigSubscription::onConfigUpdate(
// especially when it comes with per_filter_config,
provider->validateConfig(route_config);
}

std::unique_ptr<Init::ManagerImpl> noop_init_manager;
std::unique_ptr<Cleanup> resume_rds;
if (config_update_info_->onRdsUpdate(route_config, version_info)) {
stats_.config_reload_.inc();

if (config_update_info_->routeConfiguration().has_vhds() &&
config_update_info_->vhdsConfigurationChanged()) {
ENVOY_LOG(
Expand All @@ -130,7 +137,7 @@ void RdsRouteConfigSubscription::onConfigUpdate(
config_update_info_, factory_context_, stat_prefix_, route_config_providers_,
config_update_info_->routeConfiguration().vhds().config_source().resource_api_version());
vhds_subscription_->registerInitTargetWithInitManager(
noop_init_manager == nullptr ? getRdsConfigInitManager() : *noop_init_manager);
noop_init_manager == nullptr ? local_init_manager_ : *noop_init_manager);
} else {
ENVOY_LOG(debug, "rds: loading new configuration: config_name={} hash={}", route_config_name_,
config_update_info_->configHash());
Expand All @@ -146,7 +153,7 @@ void RdsRouteConfigSubscription::onConfigUpdate(
update_callback_manager_.runCallbacks();
}

init_target_.ready();
local_init_target_.ready();
}

// Initialize a no-op InitManager in case the one in the factory_context has completed
Expand All @@ -155,7 +162,7 @@ void RdsRouteConfigSubscription::onConfigUpdate(
void RdsRouteConfigSubscription::maybeCreateInitManager(
const std::string& version_info, std::unique_ptr<Init::ManagerImpl>& init_manager,
std::unique_ptr<Cleanup>& init_vhds) {
if (getRdsConfigInitManager().state() == Init::Manager::State::Initialized) {
if (local_init_manager_.state() == Init::Manager::State::Initialized) {
init_manager = std::make_unique<Init::ManagerImpl>(
fmt::format("VHDS {}:{}", route_config_name_, version_info));
init_vhds = std::make_unique<Cleanup>([this, &init_manager, version_info] {
Expand All @@ -174,8 +181,8 @@ void RdsRouteConfigSubscription::onConfigUpdate(
const Protobuf::RepeatedPtrField<envoy::service::discovery::v3::Resource>& added_resources,
const Protobuf::RepeatedPtrField<std::string>& removed_resources, const std::string&) {
if (!removed_resources.empty()) {
// TODO(#2500) when on-demand resource loading is supported, an RDS removal may make sense (see
// discussion in #6879), and so we should do something other than ignoring here.
// TODO(#2500) when on-demand resource loading is supported, an RDS removal may make sense
// (see discussion in #6879), and so we should do something other than ignoring here.
ENVOY_LOG(
error,
"Server sent a delta RDS update attempting to remove a resource (name: {}). Ignoring.",
Expand All @@ -193,7 +200,7 @@ void RdsRouteConfigSubscription::onConfigUpdateFailed(
ASSERT(Envoy::Config::ConfigUpdateFailureReason::ConnectionFailure != reason);
// We need to allow server startup to continue, even if we have a bad
// config.
init_target_.ready();
local_init_target_.ready();
}

void RdsRouteConfigSubscription::updateOnDemand(const std::string& aliases) {
Expand All @@ -207,7 +214,7 @@ bool RdsRouteConfigSubscription::validateUpdateSize(int num_resources) {
if (num_resources == 0) {
ENVOY_LOG(debug, "Missing RouteConfiguration for {} in onConfigUpdate()", route_config_name_);
stats_.update_empty_.inc();
init_target_.ready();
local_init_target_.ready();
return false;
}
if (num_resources != 1) {
Expand Down Expand Up @@ -235,11 +242,10 @@ RdsRouteConfigSubscription::loadTypeUrl(envoy::config::core::v3::ApiVersion reso

RdsRouteConfigProviderImpl::RdsRouteConfigProviderImpl(
RdsRouteConfigSubscriptionSharedPtr&& subscription,
Server::Configuration::FactoryContext& factory_context)
Server::Configuration::ServerFactoryContext& factory_context)
: subscription_(std::move(subscription)),
config_update_info_(subscription_->routeConfigUpdate()),
factory_context_(factory_context.getServerFactoryContext()),
validator_(factory_context.messageValidationVisitor()),
config_update_info_(subscription_->routeConfigUpdate()), factory_context_(factory_context),
validator_(factory_context.messageValidationContext().dynamicValidationVisitor()),
tls_(factory_context.threadLocal().allocateSlot()) {
ConfigConstSharedPtr initial_config;
if (config_update_info_->configInfo().has_value()) {
Expand Down Expand Up @@ -336,7 +342,7 @@ RouteConfigProviderManagerImpl::RouteConfigProviderManagerImpl(Server::Admin& ad

Router::RouteConfigProviderSharedPtr RouteConfigProviderManagerImpl::createRdsRouteConfigProvider(
const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds,
Server::Configuration::FactoryContext& factory_context, const std::string& stat_prefix,
Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix,
Init::Manager& init_manager) {
// RdsRouteConfigSubscriptions are unique based on their serialized RDS config.
const uint64_t manager_identifier = MessageUtil::hash(rds);
Expand All @@ -347,10 +353,8 @@ Router::RouteConfigProviderSharedPtr RouteConfigProviderManagerImpl::createRdsRo
// around it. However, since this is not a performance critical path we err on the side
// of simplicity.
RdsRouteConfigSubscriptionSharedPtr subscription(new RdsRouteConfigSubscription(
rds, manager_identifier, factory_context.getServerFactoryContext(),
factory_context.messageValidationVisitor(), factory_context.initManager(), stat_prefix,
*this));
init_manager.add(subscription->init_target_);
rds, manager_identifier, factory_context, stat_prefix, *this));
init_manager.add(subscription->parent_init_target_);
std::shared_ptr<RdsRouteConfigProviderImpl> new_provider{
new RdsRouteConfigProviderImpl(std::move(subscription), factory_context)};
dynamic_route_config_providers_.insert(
Expand All @@ -363,14 +367,14 @@ Router::RouteConfigProviderSharedPtr RouteConfigProviderManagerImpl::createRdsRo
auto existing_provider = it->second.lock();
RELEASE_ASSERT(existing_provider != nullptr,
absl::StrCat("cannot find subscribed rds resource ", rds.route_config_name()));
init_manager.add(existing_provider->subscription_->init_target_);
init_manager.add(existing_provider->subscription_->parent_init_target_);
return existing_provider;
}
}

RouteConfigProviderPtr RouteConfigProviderManagerImpl::createStaticRouteConfigProvider(
const envoy::config::route::v3::RouteConfiguration& route_config,
Server::Configuration::FactoryContext& factory_context) {
Server::Configuration::ServerFactoryContext& factory_context) {
auto provider =
std::make_unique<StaticRouteConfigProviderImpl>(route_config, factory_context, *this);
static_route_config_providers_.insert(provider.get());
Expand Down
Loading