Skip to content

Conversation

mattklein123
Copy link
Member

@mattklein123 mattklein123 commented Apr 17, 2018

I want a quick feedback as to whether this direction is worth it or not. It makes the registration boilerplate marginally better. I'm not really sure what else can be easily done.

@jmarantz WDYT? Continue?

This is in reference to #2911

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.

I like this direction, +1.

Server::Configuration::HttpFilterFactoryCb
GzipFilterFactory::createFilterFactoryFromProto(const Protobuf::Message& proto_config,
const std::string&,
Server::Configuration::FactoryContext&) {
return createFilter(
GzipFilterConfigSharedPtr config = std::make_shared<GzipFilterConfig>(
Copy link
Member

Choose a reason for hiding this comment

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

Can FactoryBase provide a method that hides the downcast? What I would do is have the GzipFilterFactory implement createFilterFactoryFromTypedProto, and pass in the already downcast variant from FactoryBase::createfilterFactoryFromProto.

Copy link
Member Author

Choose a reason for hiding this comment

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

yes I can do something like that, but the validation all has to be done here of course. I will see what I can do.

Copy link
Member

Choose a reason for hiding this comment

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

See https://github.com/envoyproxy/envoy/blob/master/include/envoy/grpc/async_client.h#L162 for an example of this pattern that I did for gRPC.

@mattklein123
Copy link
Member Author

@htuch @jmarantz PTAL. If this looks good I will do the other filters.

Copy link
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

Thanks for doing this. It looks great; you just need to fix your comments I think.

My suggestion is not to expand this to other filters yet; there may be further ways to simplify. But IMO there's no need to get it perfect first as this a solid improvement.

return createFilter(
MessageUtil::downcastAndValidate<const envoy::config::filter::http::gzip::v2::Gzip&>(
proto_config));
GzipFilterConfigSharedPtr config = std::make_shared<GzipFilterConfig>(validate(proto_config));
Copy link
Contributor

Choose a reason for hiding this comment

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

this is a huge improvement and I think we should just move forward with this. I also wonder here what in this file is specific to gzip, and couldn't be supplied by the framework as a template default of some sort. But let's go with this and we can keep iterating after merge if we think there's more ways to factor out the boilerplate.

Copy link
Member Author

Choose a reason for hiding this comment

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

My preference is to not partially do this, at least within a filter family. I would rather just do all of the HTTP filters so we don't leave things an an inconsistent state. Can we brainstorm additional ways to reduce boilerplate now?

The only thing that comes to mind is to have the base class which implements the functions, but then accepts lambdas in the constructors. It's possible this would git rid of some more code? Not sure how much of an improvement that would be though.

@htuch htuch self-assigned this Apr 18, 2018
Server::Configuration::FactoryContext&) {
NOT_IMPLEMENTED;
}

Server::Configuration::HttpFilterFactoryCb
GzipFilterFactory::createFilterFactoryFromProto(const Protobuf::Message& proto_config,
Copy link
Member

Choose a reason for hiding this comment

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

I would still argue for the typed vs. untyped variants and having createFilterFactoryFromProto defined in the superclass, with the typed variant here. This is cleaner, it saves basically a line of code and only exposes a typed interface to the subclass.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry I don't think I fully understood what you were asking for. I think I get it now. Will update.

Signed-off-by: Matt Klein <mklein@lyft.com>
@mattklein123
Copy link
Member Author

@htuch @jmarantz PTAL

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.

Approach LGTM, will take another pass when out of WIP status.

FactoryBase(const std::string& name) : name_(name) {}

private:
virtual Server::Configuration::HttpFilterFactoryCb
Copy link
Member

Choose a reason for hiding this comment

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

Should this be protected rather than private?

Copy link
Member Author

Choose a reason for hiding this comment

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

technically it can be private as it's only called by this class. Derived classes can override private functions. With that said, it doesn't matter to me one way or the other.

@mattklein123
Copy link
Member Author

I'm going to hold on this till next week when the various filter config stuff has landed as I think I will be able to clean up some of that also.

@jmarantz
Copy link
Contributor

jmarantz commented May 6, 2018

@mattklein123 if you want to pick this up again I can take another look. Once you merge master I want to patch in and play with the code so I can get a better feel.

@mattklein123
Copy link
Member Author

@jmarantz was planning on getting back to this, but also very happy to hand it over. I will merge master tomorrow so you can take a look.

Signed-off-by: Matt Klein <mklein@lyft.com>
Signed-off-by: Matt Klein <mklein@lyft.com>
@mattklein123
Copy link
Member Author

@jmarantz I merged master and also updated the factory base class to take into account the new per-route filter config which is implemented for buffer filter. Let me know what you think and whether you want to fully take this PR over or just play with it. I would like to land the HTTP stuff this week if possible (trying to clear through my backlog after the conference).

Signed-off-by: Matt Klein <mklein@lyft.com>
Signed-off-by: Matt Klein <mklein@lyft.com>
Signed-off-by: Matt Klein <mklein@lyft.com>
Signed-off-by: Matt Klein <mklein@lyft.com>
@@ -21,7 +21,7 @@ message HealthCheck {

// Specifies the incoming HTTP endpoint that should be considered the
// health check endpoint. For example */healthcheck*.
string endpoint = 2 [(validate.rules).string.min_bytes = 1, deprecated = true];
string endpoint = 2 [deprecated = true];
Copy link
Member Author

Choose a reason for hiding this comment

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

This was exposed with improved testing via my changes.

@mattklein123
Copy link
Member Author

@htuch @jmarantz PTAL I updated the rest of the HTTP filters. Assuming this looks good, would like to merge and we can always improve more in the future. I will do something similar for the network filters next.

@mattklein123 mattklein123 changed the title [RFC] Less filter boilerplate http filters: less filter factory boilerplate May 11, 2018
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.

This is rad, some minor comments.

@@ -17,7 +16,7 @@ namespace Extensions {
namespace HttpFilters {
namespace BufferFilter {

Http::FilterFactoryCb BufferFilterConfigFactory::createFilter(
Http::FilterFactoryCb BufferFilterFactory::createTypedFilterFactoryFromProto(
Copy link
Member

Choose a reason for hiding this comment

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

Nit: for consistency with gRPC, maybe this should have Typed as a suffix, same with per-route.

}

ProtobufTypes::MessagePtr createEmptyConfigProto() override {
return ProtobufTypes::MessagePtr{new ConfigProto()};
Copy link
Member

Choose a reason for hiding this comment

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

Nit: std::make_unique?

@@ -1,3 +1,5 @@
#include "envoy/config/filter/http/squash/v2/squash.pb.validate.h"
Copy link
Member

Choose a reason for hiding this comment

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

How come we started to need this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because now the factory has built-in validation which wasn't happening before in all cases and the include is only in the .cc file.

Signed-off-by: Matt Klein <mklein@lyft.com>
Signed-off-by: Matt Klein <mklein@lyft.com>
@mattklein123
Copy link
Member Author

@htuch updated

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.

Wh00t.

@mattklein123 mattklein123 merged commit 01fef5b into master May 11, 2018
@mattklein123 mattklein123 deleted the registration_fixes branch May 11, 2018 20:22
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.

3 participants