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

Added static registration for http tracers. (#967) #994

Merged
merged 8 commits into from
May 24, 2017

Conversation

mrice32
Copy link
Member

@mrice32 mrice32 commented May 18, 2017

Added a static registration mechanism (following the pattern of filters mentioned in the comments on #967) for http tracers. This will likely be expanded to a more general registration mechanism in future work. This PR is part of the work towards solving #967.

@mattklein123
Copy link
Member

I think @htuch will take first pass, but meta comment, if this goes in I think #982 can lose the defines and just not compile lightstep code. I think this will also solve @lizan issue.


Envoy::Runtime::RandomGenerator& rand = server.random();

std::unique_ptr<lightstep::TracerOptions> opts(new lightstep::TracerOptions());
Copy link
Contributor

Choose a reason for hiding this comment

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

Please include lightstep/options.h and lightstep/tracer.h

* Implemented by each network filter and registered via registerHttpTracerFactory() or
* the convenience class RegisterHttpTracerFactory.
*/
class HttpTracerFactory {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a good reason to NOT put this in include/envoy/tracing/http_tracer.h?

Copy link
Member Author

Choose a reason for hiding this comment

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

It creates a build dependency cycle because //include/envoy/tracing:http_tracer_interface and //include/envoy/server:instance_interface would both depend on one another.

@@ -44,6 +45,19 @@ class NetworkFilterConfigFactory {
};

/**
* Implemented by each network filter and registered via registerHttpTracerFactory() or
Copy link
Contributor

Choose a reason for hiding this comment

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

Implemented for each kind of HttpTracer.

public:
virtual ~HttpTracerFactory() {}

virtual Tracing::HttpTracerPtr
Copy link
Contributor

Choose a reason for hiding this comment

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

Please document the method (expected behavior, error conditions).

if (http_tracer) {
http_tracer_ = std::move(http_tracer);
found_tracer = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

break;

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

lgtm, nice work. Small nit, will let others follow up with other comments/approve.

@@ -135,6 +159,11 @@ class MainImpl : Logger::Loggable<Logger::Id::config>, public Main {
return filter_config_factories;
}

static std::list<HttpTracerFactory*>& httpTracerFactories() {
static std::list<HttpTracerFactory*> http_tracer_factories;
Copy link
Member

Choose a reason for hiding this comment

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

If we are following the letter of the law here I think this should be a pointer and the list allocated with new

@mattklein123
Copy link
Member

@mrice32 also please sign the CLA

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for adding this!

template <class T> class RegisterHttpTracerFactory {
public:
RegisterHttpTracerFactory() {
static T instance;
Copy link
Member

Choose a reason for hiding this comment

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

In addition to the above static std::list, this should also be created on use. For reference:

https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use

class ZipkinHttpTracerFactory : public HttpTracerFactory {
public:
// HttpTracerFactory
Tracing::HttpTracerPtr tryCreateHttpTracer(const std::string& type,
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit surprised by the interface (although it's consistent with the existing factory interface for filters). How come we need to probe each individual filter/tracer to figure out if they match type, rather than registering a map from type to filter/tracer? @mattklein123 for the filter interface.

Copy link
Member

Choose a reason for hiding this comment

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

We should do that. :) I have no idea why I did it this way in the first place. Very long time ago now. Feel free to fix in this PR or a follow up.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay, cool. I'll add it into this PR.

Copy link
Member

Choose a reason for hiding this comment

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

This has the added benefit of you can fail if you try to register something with the same name. So would be great to add test for that also, and fix all the networking filters too. Bigger change, but I think well worth it.

@mrice32
Copy link
Member Author

mrice32 commented May 19, 2017

Took a stab at the map static registration mechanism, PTAL.

@ccaraman
Copy link
Contributor

CLA has been signed.

Json::Exception);
}

TEST(NetworkFilterConfigTest, DoubleRegistrationTest) {
EXPECT_THROW(RegisterNetworkFilterConfigFactory<ClientSslAuthConfigFactory>(), EnvoyException);
Copy link
Member

Choose a reason for hiding this comment

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

nit: I think EXPECT_THROW_WITH_MESSAGE makes a test slightly better (that macro is from common_test/utility.h)
In Envoy we throw EnvoyExceptions for various reasons it's better to verify that it's what we expect.

const Json::Object& config,
Server::Instance& server) PURE;
/**
* Create a particular network filter factory implementation. If the creation fails, an error will
Copy link
Member

Choose a reason for hiding this comment

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

can you be more specific, is it only EnvoyException which can be thrown?

* Create a particular network filter factory implementation. If the creation fails, an error will
* be thrown. The returned callback should always be valid.
*/
virtual NetworkFilterFactoryCb createFilterFactory(NetworkFilterType type,
Copy link
Member

Choose a reason for hiding this comment

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

i think we are a bit more strict now around documenting @params etc, can you add those

static std::list<NetworkFilterConfigFactory*> filter_config_factories;
return filter_config_factories;
static std::unordered_map<std::string, NetworkFilterConfigFactory*>& filterConfigFactories() {
static std::unordered_map<std::string, NetworkFilterConfigFactory*>* filter_config_factories =
Copy link
Member

Choose a reason for hiding this comment

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

any cons that to be: static std::unordered_map<std::string, NetworkFilterConfigFactory*> filter_config_factories; ?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the static initialization order fiasco :) See https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use. We have a section on this now in https://github.com/lyft/envoy/blob/master/STYLE.md.

Copy link
Member

Choose a reason for hiding this comment

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

oki doki, i have not inspected all the code, but looks like https://github.com/lyft/envoy/blob/master/source/server/config/network/http_connection_manager.h#L117 has a similar issue as you pointed out @htuch

throw EnvoyException(fmt::format("unable to create http filter factory for '{}'/'{}'",
string_name, string_type));
}
HttpFilterConfigFactory* factory = filterConfigFactories().at(string_name);
Copy link
Member

Choose a reason for hiding this comment

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

do we have a test when we call it without "string_name" filtered registered

* Provides the identifying name for a particular implementation of an http filter produced by the
* factory.
*/
virtual std::string name() PURE;
Copy link
Member

Choose a reason for hiding this comment

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

nbd (as there are calls to it only on a startup)
but this could be const std::string&

Copy link
Member Author

Choose a reason for hiding this comment

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

I was curious about this. We would need to define a string as a member of the class or make a static string, right? If I'm thinking about it correctly, both of those options would ultimately be more copying than the current version (because we should only call the method once during registration and the string produced will be moved into the unordered_map as opposed to the copy required for a const std::string &). However, if this is just a readability/API preference for envoy, that totally makes sense.

Copy link
Member

Choose a reason for hiding this comment

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

yeah, we could do static const string in a class.
Thinking about this more, as it's called once there is no point of having ref returned, agreed.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

LGTM after @RomanDzhabarov comments are taken care of. I think you can easily add a shim to support the legacy filter API. The filters that you've converted here are good for the new API, but it would make sense to have a test for at least one dummy filter (just duplicate the Echo filter maybe) that conforms to the deprecated API to ensure we don't regress there until 1.4.0.

const Json::Object&,
const std::string& stat_prefix,
Server::Instance& server) {
if (type != HttpFilterType::Both) {
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated to the review, a question that came up recently while discussing filters with @alyssawilk. Why is Envoy filter config structured such that (1) filters know their HttpFilterType yet (2) the type is specified in the config as well, meaning we need to check consistency. It seems this could be elided from the config. The only thing I can think of is that some filters might work as encoder/decoder depending upon configuration... @RomanDzhabarov @ccaraman @junr03 for insight here.

Copy link
Member

Choose a reason for hiding this comment

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

@htuch cannot think about anything else, but fwiw, currently, no HTTP filters support this behavior.

static std::list<NetworkFilterConfigFactory*> filter_config_factories;
return filter_config_factories;
static std::unordered_map<std::string, NetworkFilterConfigFactory*>& filterConfigFactories() {
static std::unordered_map<std::string, NetworkFilterConfigFactory*>* filter_config_factories =
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the static initialization order fiasco :) See https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use. We have a section on this now in https://github.com/lyft/envoy/blob/master/STYLE.md.

@mrice32
Copy link
Member Author

mrice32 commented May 23, 2017

Thanks @RomanDzhabarov for the thorough review. It's really helpful as I'm trying to learn the how things should be done in envoy. I believe I have corrected for most of the comments except for one that I had a question about. @htuch I have updated to add the backwards compatibility. I documented the list registration related methods/classes as DEPRECATED in the comments. Please let me know if there's some other place I should document the deprecation. I will add a dummy test to ensure that the deprecated filter registration continues to work and commit it today.

@RomanDzhabarov
Copy link
Member

LGTM, @htuch for final pass

@htuch htuch merged commit 3a466c3 into envoyproxy:master May 24, 2017
@mrice32 mrice32 deleted the registration branch May 24, 2017 15:37
rshriram pushed a commit to rshriram/envoy that referenced this pull request Oct 30, 2018
Automatic merge from submit-queue.

JWT-auth: Support aud as string array

**What this PR does / why we need it**:

To support "aud" in JWT as string array.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
None
```
jpsim pushed a commit that referenced this pull request Nov 28, 2022
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
jpsim pushed a commit that referenced this pull request Nov 29, 2022
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
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.

None yet

7 participants