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

compressor: expose generic compressor filter to users #10553

Merged
merged 65 commits into from
May 8, 2020

Conversation

rojkov
Copy link
Member

@rojkov rojkov commented Mar 27, 2020

Description:

Currently the generic HTTP compressor filter isn't exposed to users
even though it's used internally by envoy.filters.http.gzip and can be
used by external filter extensions.

Expose the compressor's config API to users. For example the filter
can be configured as follows:

    ...
    filter_chains:
      filters:
      - name: envoy.http_connection_manager
        config:
           http_filters:
           - name: envoy.filters.http.compressor
             config:
               disable_on_etag_header: true
               content_length: 100
               content_type:
                 - text/html
                 - application/json
               compressor_library:
                 name: text_optimized
                 typed_config:
                   "@type": type.googleapis.com/envoy.extensions.filters.http.compressor.gzip.v3.Gzip
                   memory_level: 3
                   window_bits: 10
                   compression_level: best
                   compression_strategy: default_strategy
    ...

Multiple compressor filters using different compressor libraries,
e.g. gzip and brotli, can be stacked in one filter chain.

Risk Level: Medium
Testing: unit tests, manual testing
Docs Changes: a page for the new compressor filter is added, also comments in compressor.proto were updated.
Release Notes: added a link to compressor's doc to version_history.rst

Currently the generic HTTP compressor filter isn't exposed to users
even though it's used internally by `envoy.filters.http.gzip` and can be
used by external filter extensions.

Expose the compressor's config API to users. For example the filter
can be configured as follows:

    ...
    filter_chains:
      filters:
      - name: envoy.http_connection_manager
        config:
          http_filters:
          - name: envoy.filters.http.compressor
            config:
              disable_on_etag_header: true
              content_length: 100
              content_type:
                - text/html
                - application/json
              compressor_library:
                name: envoy.filters.http.compressor.gzip
                config:
                  memory_level: 3
                  window_bits: 10
                  compression_level: best
                  compression_strategy: rle
    ...

Multiple compressor filters using different compressor libraries,
e.g. gzip and brotli, can be stacked in one filter chain.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
@rojkov rojkov requested a review from dio as a code owner March 27, 2020 11:15
@repokitteh-read-only
Copy link

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/.

🐱

Caused by: #10553 was opened by rojkov.

see: more, trace.

@rojkov
Copy link
Member Author

rojkov commented Mar 27, 2020

/cc @junr03, @rebello95, @mattklein123

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
@mattklein123 mattklein123 self-assigned this Mar 27, 2020
Dmitry Rozhkov added 2 commits March 30, 2020 10:36
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
@@ -0,0 +1,62 @@
syntax = "proto3";
Copy link
Member

Choose a reason for hiding this comment

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

How does this relate to https://github.com/envoyproxy/envoy/blob/master/api/envoy/config/filter/http/gzip/v2/gzip.proto? Which one should service operators configure and when? Is the former deprecated?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, exactly, the former is deprecated. We need to make that clear as @htuch points out, have text in deprecated.rst, and also make sure the deprecated feature warning/stat is incremented so that operators know thy need to upgrade.

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.

Thanks a ton for working on this. Per @htuch can we nail the deprecation story? Also, please check clang-tidy. It works now and there may be existing and new issues you need to fix. Thank you!

/wait

@@ -0,0 +1,62 @@
syntax = "proto3";
Copy link
Member

Choose a reason for hiding this comment

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

Yes, exactly, the former is deprecated. We need to make that clear as @htuch points out, have text in deprecated.rst, and also make sure the deprecated feature warning/stat is incremented so that operators know thy need to upgrade.

Dmitry Rozhkov added 2 commits March 31, 2020 12:22
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
@rojkov
Copy link
Member Author

rojkov commented Mar 31, 2020

Thank you! I've just marked the old gzip filter explicitly deprecated.

But since it warns users now I wonder if we should revert #10306 and make gzip use its old implementation.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
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.

Looks good, a few more API comments..

// [#next-free-field: 10]
message Gzip {
enum CompressionStrategy {
DEFAULT = 0;
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 comment on what the DEFAULTs are here and below? These should be fixed in the API.

api/envoy/config/filter/http/compressor/gzip/v2/gzip.proto Outdated Show resolved Hide resolved
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.

Thanks in general this is awesome. Let's nail all of the API comments and then we can do the in-depth review. Thank you!

/wait

//
// This field is ignored when used in the context of the deprecated "envoy.filters.http.gzip"
// filter.
CompressorLibrary compressor_library = 6;
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 not sure it makes sense to have a default here. Can we require this and then make the gzip config explicit for clarity?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, this field is required now.

Copy link
Member

Choose a reason for hiding this comment

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

Can we make it required via annotation?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm... This message is used also in the deprecated envoy.filters.http.gzip filter. I guess there are two options:

  1. revert gzip: make use of generalized compression filter #10306 completely or partially (drop the compressor field from the Gzip message);
  2. duplicate compressor.proto for envoy.filters.http.gzip.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
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.

In general looks awesome, thanks. Just a few more high level API comments. Thank you!

/wait

Comment on lines 63 to 64
// The name of the compressor library to instantiate for the filter.
string name = 1 [(validate.rules).string = {min_bytes: 1}];
Copy link
Member

Choose a reason for hiding this comment

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

We can remove this for new extensions as the extension will be looked up via the typed_config.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeap, removed.

//
// This field is ignored when used in the context of the deprecated "envoy.filters.http.gzip"
// filter.
CompressorLibrary compressor_library = 6;
Copy link
Member

Choose a reason for hiding this comment

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

Can we make it required via annotation?

Dmitry Rozhkov added 2 commits April 7, 2020 14:42
Since Envoy::Compressor::ZlibCompressorImpl::CompressionStrategy is
simply static_cast'ed to uint64_t the Standard strategy (4)
becomes Z_FIXED (4 as well). This basically disables the use of
dynamic Huffman codes when the gzip filter is configured to use
default values.

Make the Standard strategy equal to 0 to translate to
Z_DEFAULT_STRATEGY.

Contributes to envoyproxy#8448

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Dmitry Rozhkov added 2 commits May 4, 2020 12:13
@junr03
Copy link
Member

junr03 commented May 4, 2020

@rojkov awesome work! Seems like you got @htuch's comment resolved. Any thoughts on #10553 (comment)?

Alternatively, we could add a "name" or "stat_prefix" field to the compressor filter config, and use that.

The more I think about it, the more I like this option. It would be a pretty unobtrusive way to disambiguate stats trees from different compression filters without affecting the filter interface.

@rojkov
Copy link
Member Author

rojkov commented May 5, 2020

The more I think about it, the more I like this option. It would be a pretty unobtrusive way to disambiguate stats trees from different compression filters without affecting the filter interface.

Agree. I like "stats_prefix" as more explicit, but would prefer it to be optional to keep minimal configs light. Are you ok with that?

Copy link
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

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

would prefer it to be optional to keep minimal configs light

That sounds good to me. Include it if present.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
@repokitteh-read-only
Copy link

CC @envoyproxy/api-watchers: FYI only for changes made to api/.

🐱

Caused by: #10553 was synchronize by rojkov.

see: more, trace.

@rojkov
Copy link
Member Author

rojkov commented May 6, 2020

That sounds good to me. Include it if present.

Done!
I decided not to mandate a separator at the end of the prefix, e.g. one might want to have an underscore instead of a dot.

// Prefix added to the names of stats generated by this filter. It can be used to disambiguate stats
// trees from different compression filters. For example stats of a compressor filter limited to compress
// binaries blobs and tweaked accordingly can be prefixed with "bins.". And another compressor filter
// tweaked co compress text content only can be prefixed with "text.".
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// tweaked co compress text content only can be prefixed with "text.".
// tweaked to compress text content only can be prefixed with "text.".

super small typo. I can fix in my PR.

junr03
junr03 previously approved these changes May 6, 2020
Copy link
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

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

AWESOME! Amazing work @rojkov. Thank you for working with us on iterating and getting this landed. I can't wait to see all the compression extensions we build on top of this!

@junr03
Copy link
Member

junr03 commented May 6, 2020

@htuch @mattklein123 can either of you do a final pass to get the api-shepherds approval?

@mattklein123 mattklein123 self-assigned this May 6, 2020
message CompressorLibrary {
// Compressor library specific configuration. See the supported libraries for further
// documentation.
google.protobuf.Any typed_config = 1;
Copy link
Member

Choose a reason for hiding this comment

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

Can we move this one to the new TypedConfig that will appear in #10908?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, I've subscribed to that PR.

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 presume it's about TypedExtensionConfig, not TypedConfig?

Copy link
Member

Choose a reason for hiding this comment

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

Ack

Copy link
Member

Choose a reason for hiding this comment

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

@htuch If we are moving all the typed_configs across the project to the new TypedExtenstionConfig message that is being created in #10908, this could be updated then. I'd like to merge this and come back and update when the discussion in #10908 settles, and gets merged. We have been working on this PR for a while, and have a chain of a few other PRs that depend on this one.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can move them all without a deprecation and major version change. The idea is to make all new ones TypedExtensionConfig. Would it satisfy your concern if I submit a quick PR to introduce this independent of #10908?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can move them all without a deprecation and major version change.

Yep, I was suggesting we would be doing the config in this PR as part of the deprecation that all other extensions would have to go through. But I see the want to wait a bit to land the correct thing that would avoid adding more volume to the deprecation cycle. Thanks for #11105, hopefully we can get that in soon, and move this PR along :)

Compression::Compressor::CompressorFactoryPtr compressor_factory)
: Common::Compressors::CompressorFilterConfig(
generic_compressor,
stats_prefix + "compressor." + generic_compressor.stats_prefix() +
Copy link
Member

@junr03 junr03 May 7, 2020

Choose a reason for hiding this comment

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

now that #11105 merged, we can delete the stats_prefix field, and use generic_compressor.compressor_library().typed_config().name().

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.

Nice, LGTM other than remaining merge and field replacement.

/wait

Dmitry Rozhkov added 3 commits May 8, 2020 12:04
This reverts commit 4b4cfda.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
@rojkov
Copy link
Member Author

rojkov commented May 8, 2020

Do we really need the CompressorLibrary message now when there is this standard Envoy-specific TypedExtensionConfig? I remember I had to introduce the new message to accommodate config and typed_config, but then we moved to typed_configs only and now the message looks redundant.

I've replaced CompressorLibrary with TypedExtensionConfig and the configuration of compressors still looks sane imho.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Copy link
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

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

@htuch any opinion around this? Otherwise, LGTM


// [#protodoc-title: Compressor Library]

message CompressorLibrary {
Copy link
Member

Choose a reason for hiding this comment

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

I guess the point of this message was to potentially have fields that were common to all compressor extensions. However, if we believe there won't be a case for this, I am happy to delete.

@mattklein123
Copy link
Member

@rojkov friendly request to please never force push as it makes reviews more difficult, thank you!

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.

Thank you! Agreed on the message simplification.

@repokitteh-read-only repokitteh-read-only bot removed the api label May 8, 2020
@mattklein123 mattklein123 merged commit 49efb98 into envoyproxy:master May 8, 2020
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.

4 participants