Skip to content

cleanup common factory context using#31072

Merged
wbpcode merged 34 commits intoenvoyproxy:mainfrom
wbpcode:dev-clean-common-factory-context
Dec 4, 2023
Merged

cleanup common factory context using#31072
wbpcode merged 34 commits intoenvoyproxy:mainfrom
wbpcode:dev-clean-common-factory-context

Conversation

@wbpcode
Copy link
Copy Markdown
Member

@wbpcode wbpcode commented Nov 28, 2023

Commit Message: cleanup common factory context using
Additional Description:

Part of factory context refactoring and clean up. This PR clean up all remaining CommonFactoryContext using.

Risk Level: mid.
Testing: n/a.
Docs Changes: n/a.
Release Notes: n/a.
Platform Specific Features: n/a.

@wbpcode
Copy link
Copy Markdown
Member Author

wbpcode commented Nov 28, 2023

Note: The target of this patch is not to remove all CommonFactoryContext, but to ensure all position that take CommonFactoryContext as parameter will use ServerFactoryContext as argument rather than using FactoryContext.

Then, we can break the inheritance relationship between CommonFactoryContext and FactoryContext. And in the future, the CommonFactoryContext could be treated as a limited ServerFactoryContext.

Based on above target, this cleanup did different things for different scenarios.

  1. For the CommonFactoryContext that always be used in the listener scope, we will change it to FactoryContext directly. This is safe and have no any side effect. See the request id extension for an example.

  2. For the ComonFactoryContext that always be used in the server scope, we do nothing to it. It's basically OK. See the cluster specifer plugin https://github.com/envoyproxy/envoy/blob/main/envoy/router/cluster_specifier_plugin.h#L38 as an example.

  3. For the ComonFactoryContext that may be used in both listener scope and server scope, I updated code base to always use ServerFactoryContext as the argument. This may bring potential risk because a ServerFactoryContext powered CommonFactoryContext has different scope(), initManager(), etc. with FactoryContext powered CommonFactoryContext. The lucky thing is that we never use these methods in our code base so it's safe to update it directly. This still may effect third-party forks (Although I think the possibility is very low because only the Formatter and CustomResponse will be effected and these extension point rarely use methods like scope(), etc.).

Signed-off-by: wbpcode <wbphub@live.com>
@wbpcode wbpcode force-pushed the dev-clean-common-factory-context branch from 4a5af94 to 67c3c79 Compare November 28, 2023 03:10
Comment on lines +197 to +216
/**
* Factory context for configuration parsing and initiation. This context contains server factory
* context reference and a validation visitor from uncertain context (server, listener, cluster or
* others).
*/
class ConfigFactoryContext {
public:
virtual ~ConfigFactoryContext() = default;

/**
* @return ServerFactoryContext which lifetime is no shorter than the server and provides
* access to the server's resources.
*/
virtual ServerFactoryContext& getServerFactoryContext() const PURE;

/**
* @return ProtobufMessage::ValidationVisitor& validation visitor for configuration messages.
*/
virtual ProtobufMessage::ValidationVisitor& messageValidationVisitor() const PURE;
};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Formatter extensions maybe used in both server scope and listener scope. We should use different for message validation visitors in different scopes.

See #31073 for more context.

Comment on lines -27 to +28
virtual Http::RequestIDExtensionSharedPtr
createExtensionInstance(const Protobuf::Message& config, CommonFactoryContext& context) PURE;
virtual Http::RequestIDExtensionSharedPtr createExtensionInstance(const Protobuf::Message& config,
FactoryContext& context) PURE;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This change is complete safe because the request id extension is only used in the listener scope. We change the CommonFactoryContext here to FactoryContext directly.

Comment on lines +15 to +16
auto connectivity_manager = Network::ConnectivityManagerFactory{context}.get();
auto connectivity_manager =
Network::ConnectivityManagerFactory{context.getServerFactoryContext()}.get();
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This bring a possible logic change. The messageValidationVistior() of server factory context will be used always by the DnsCacheImpl. This is wrong, see See #31073 for more detail.

I will revise this.

Comment on lines +40 to +43
auto typed_config = Envoy::Config::Utility::translateAnyToFactoryConfig(
formatter.typed_config(), context.messageValidationVisitor(), *factory);
auto parser = factory->createCommandParserFromProto(*typed_config, context);
auto parser =
factory->createCommandParserFromProto(*typed_config, context.getServerFactoryContext());
Copy link
Copy Markdown
Member Author

@wbpcode wbpcode Nov 28, 2023

Choose a reason for hiding this comment

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

This bring potential logic change to third party forks (with very low possibility). Because scope(), initManager(), etc methods are different in the FactoryContext and ServerFactoryContext.

But lucky we never use it in our current formatter extensions. (metadata and req_without_query formatters didn't use any context and cel formatter use singleton context only.)


BodyFormatter(const envoy::config::core::v3::SubstitutionFormatString& config,
Server::Configuration::CommonFactoryContext& context)
Server::Configuration::FactoryContext& context)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Safe because the BodyFormatter only be used in the listener scope.

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.

sorry shouldn't thinks in the listener scope have a genericfactorycontext with stats and init manager scoped to the listener?

Copy link
Copy Markdown
Member Author

@wbpcode wbpcode Nov 30, 2023

Choose a reason for hiding this comment

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

Yeah, generic factory context is enough for this scenario. I use FactoryContext just for convenience. I will update it.

std::vector<Value>
Config::parse(const Protobuf::RepeatedPtrField<FilterStateValueProto>& proto_values,
Server::Configuration::CommonFactoryContext& context) const {
Server::Configuration::ConfigFactoryContext& context) const {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The dependency to the Formatter result in this change.

Signed-off-by: wbpcode <wbphub@live.com>
@wbpcode wbpcode requested a review from lizan as a code owner November 28, 2023 04:30
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
@alyssawilk
Copy link
Copy Markdown
Contributor

hm, regarding (3) I thought the plan long term was to have a FactoryContext class which had
serverFactoryContext()
scope()
initManager()

as the latter two are the only things overridden. For (3) I wonder if we should create that class now, and have a simple wrapper converter so folks can still use those? Want to get thoughts before digging in.

@alyssawilk
Copy link
Copy Markdown
Contributor

/retest

@alyssawilk
Copy link
Copy Markdown
Contributor

/wait on CI

@wbpcode
Copy link
Copy Markdown
Member Author

wbpcode commented Nov 29, 2023

as the latter two are the only things overridden.

In fact, drainDecison() and messageValidationVisitor() also should be overridden. 🤣

For (3) I wonder if we should create that class now, and have a simple wrapper converter so folks can still use those? Want to get thoughts before digging in.

I hesitate now. I cannot image in which case the developers may use socpe() or initManager() in Formatter. But we did change something.

@wbpcode
Copy link
Copy Markdown
Member Author

wbpcode commented Nov 29, 2023

Ok, let's create a GenericFactoryContext for these scenarios. And if third party forks extended these extension points in the (3), a compile error will be throwed and they know they need update their implementation.

Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Copy link
Copy Markdown
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

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

almost there!
/wait


BodyFormatter(const envoy::config::core::v3::SubstitutionFormatString& config,
Server::Configuration::CommonFactoryContext& context)
Server::Configuration::FactoryContext& context)
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.

sorry shouldn't thinks in the listener scope have a genericfactorycontext with stats and init manager scoped to the listener?

// TODO(wbpcode): these is a potential bug of message validation. The validation visitor
// of server context should not be used here directly. But this is bug is not introduced
// by this PR and will be fixed in the future.
Server::GenericFactoryContextImpl generic_context(context, context.messageValidationVisitor());
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.

mm, if this may be a problem shouldn't we not switch to server factory context here? I'd think if we wanted to inherit validation we'd need to keep this a generic.

LocalResponsePolicy(const envoy::extensions::http::custom_response::local_response_policy::v3::
LocalResponsePolicy& config,
Server::Configuration::CommonFactoryContext& context);
Server::Configuration::ServerFactoryContext& context);
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.

In general passing Generic makes more sense than server in case folks want (properly scoped) stats down the road WDYT?

Copy link
Copy Markdown
Member Author

@wbpcode wbpcode Nov 30, 2023

Choose a reason for hiding this comment

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

Actually, in previous implementation, the backend of CommonFactoryContext here will always be a ServerFactoryContext.

As I said in the TODO, this potential bug is not introduced by this patch. The LocalResponsePolicy will be created in the createPolicy method which will always take a ServerFactoryContext.

This patch just wrappered the ServerFactoryContext to a GenericFactoryContext (for Formatter usage) and doesn't change any logic or behavior here.

See:

Extensions::HttpFilters::CustomResponse::PolicySharedPtr
LocalResponseFactory::createPolicy(const Protobuf::Message& config,
                                   Envoy::Server::Configuration::ServerFactoryContext& context,
                                   Stats::StatName) {
  const auto& local_response_config =
      MessageUtil::downcastAndValidate<const LocalResponsePolicyProto&>(
          config, context.messageValidationVisitor());
  return std::make_shared<LocalResponsePolicy>(local_response_config, context);
}

Copy link
Copy Markdown
Member Author

@wbpcode wbpcode Nov 30, 2023

Choose a reason for hiding this comment

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

Although I think we should fix this bug (this is why I left a TODO and #31073), but the fix also a behavior change. I don't want introduce any additional behavior changes (except we have no choice) in this big PR.

But if you still think to fix it here make sense, I also can update it. :)

Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Comment thread test/integration/BUILD
Comment on lines 353 to -360
"//source/extensions/clusters/strict_dns:strict_dns_cluster_lib",
"//source/extensions/load_balancing_policies/cluster_provided:config",
"//source/extensions/load_balancing_policies/least_request:config",
"//source/extensions/load_balancing_policies/maglev:config",
"//source/extensions/load_balancing_policies/random:config",
"//source/extensions/load_balancing_policies/ring_hash:config",
"//source/extensions/load_balancing_policies/round_robin:config",
"//source/extensions/load_balancing_policies/subset:config",
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Seems this patch add some more symbols and result in coverage linking failure. I removed some unnecessary extensions here to make the CI green. orz.

Signed-off-by: wbpcode <wbphub@live.com>
@wbpcode
Copy link
Copy Markdown
Member Author

wbpcode commented Nov 30, 2023

Coverage.... But at least I know how to fix it... let me do it tomorrow.

Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
Signed-off-by: wbpcode <wbphub@live.com>
@wbpcode
Copy link
Copy Markdown
Member Author

wbpcode commented Dec 2, 2023

finally......

@wbpcode wbpcode merged commit 5bc7a8c into envoyproxy:main Dec 4, 2023
@wbpcode wbpcode deleted the dev-clean-common-factory-context branch December 4, 2023 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants