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

filter: Add an incomplete pluggable HTTP caching filter (CacheFilter). #7198

Closed
wants to merge 121 commits into from

Conversation

toddmgreer
Copy link
Contributor

Description: Adds CacheFilter, an HTTP filter that caches response. To support a variety of needs, storage is delegated to a plugin cache implementation, but CacheFilter handles the detailed logic of determining what can be cached, whether to serve a particular cache entry for a particular request, and validation.

Design: eCache: a multi-backend HTTP cache for Envoy

This initial submission establishes the framework for cache implementations (including a simple example plugin), and handles basic integration with Envoy as an HTTP filter. It doesn't yet handle enough of the RFCs to be used, and the tests only validate basic functionality. While there is substantial work remaining, merging this now will make it easier for development of cache plugins to happen in wile the filter side is finished.

Risk Level: Low. Since there are no (non-test) uses of this new filter, it would be difficult for it to break anything. The only changes to actually executed code are two new HeaderMap inline headers and the new static factory registration.

Testing: All components have basic unit tests. Integration tests and more unit tests will be needed before CacheFilter is ready for production use.

Docs Changes: The new config proto (envoy.config.filter.http.cache.v2alpha.Cache) has reasonable documentation, and has been added to docs/build.sh.

Release Notes: N/A

#868

Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
@mattklein123
Copy link
Member

@envoyproxy/maintainers any volunteers to shepherd review on this? I don't have the bandwidth to take this on.

@jmarantz jmarantz self-assigned this Jun 10, 2019
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
@toddmgreer
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🐴 hold your horses - no failures detected, yet.

🐱

Caused by: a #7198 (comment) was created by @toddmgreer.

see: more, trace.

@toddmgreer toddmgreer marked this pull request as ready for review June 11, 2019 19:56
@stale
Copy link

stale bot commented Jun 18, 2019

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Jun 18, 2019
@jmarantz
Copy link
Contributor

/wait

@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Jun 18, 2019
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.

flushing comments

source/extensions/filters/http/cache/cache_filter.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/cache_filter.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/cache_filter.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/cache_filter.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.cc Outdated Show resolved Hide resolved
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.

OK I think I'm done with this pass; can you address these and I'll dig deeper?

source/extensions/filters/http/cache/http_cache.h Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.h Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache.h Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache_utils.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache_utils.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache_utils.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache_utils.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/http_cache_utils.cc Outdated Show resolved Hide resolved
source/extensions/filters/http/cache/simple_http_cache.h Outdated Show resolved Hide resolved
* source/common/http/headers.h:

Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
Signed-off-by: Todd Greer <tgreer@google.com>
… ref.

Signed-off-by: Todd Greer <tgreer@google.com>
@enozcan
Copy link

enozcan commented Jan 25, 2020

Hi @toddmgreer, I have implemented http cache backed by Hazelcast IMDG with the completed features on the filter side (repository). I’m planning to make some changes (i.e. formatting the code style to make it consistent with Envoy cpp style, etc. ) but the caching logic will be more or less the same. What about using it as a reference implementation or the default provider? I believe implementing the filter hand in hand with a provider would make sense and once the filter is ready for production, a plugin can be provided as well.

@mattklein123
Copy link
Member

/azp run envoy-linux

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@toddmgreer
Copy link
Contributor Author

Hi @enozcan, that's fantastic--I'm excited to see new work building on CacheFilter! HazelcastHttpCache seems like a perfect candidate to be included with Envoy (though that will ultimately be up to Envoy's senior maintainers). I don't intend for there to be a default provider / HttpCache implementation--the configuration should specify something, but HazelcastHttpCache makes perfect sense as one of the built-in options.

Any complaints about the interfaces? Were they clear enough?

Thank you for extending Envoy/CacheFilter!

@toddmgreer
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🐴 hold your horses - no failures detected, yet.

🐱

Caused by: a #7198 (comment) was created by @toddmgreer.

see: more, trace.

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, left some more comments. At a high level this LGTM. TBH my advice for getting this merged at this point is to start splitting this into small PRs that we can re-review without the massive size of this PR. You could easily start with a PR for the utilities, then the cache itself, then the filter, then the simple cache implementation, etc. I think if we do that @jmarantz and I can commit to efficiently re-reviewing and we can land this? WDYT? Thank you for all your work here.

/wait


CacheFilterSharedPtr self = shared_from_this();
ENVOY_STREAM_LOG(debug, "CacheFilter::decodeHeaders starting lookup", *decoder_callbacks_);
lookup_->getHeaders([self](LookupResult&& result) { onHeadersAsync(self, std::move(result)); });
Copy link
Member

Choose a reason for hiding this comment

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

Can this async lambda ever fire inline? I could imagine it can and we need to deal with this case?

Http::FilterDataStatus CacheFilter::encodeData(Buffer::Instance& data, bool end_stream) {
if (insert_) {
ENVOY_STREAM_LOG(debug, "CacheFilter::encodeHeaders inserting body", *encoder_callbacks_);
// TODO(toddmgreer): Wait for the cache if necessary.
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 waiting for the cache, you will also have to apply back pressure potentially. Can you make sure this is covered by an open issue?

case CacheEntryStatus::RequiresValidation:
case CacheEntryStatus::FoundNotModified:
case CacheEntryStatus::UnsatisfiableRange:
ASSERT(false); // We don't yet return or support these codes.
Copy link
Member

Choose a reason for hiding this comment

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

Switch to NOT_IMPLEMENTED macro

Comment on lines +158 to +161
ASSERT(false, "CacheFilter doesn't call getBody unless there's more body to get, so this is a "
"bogus callback.");
decoder_callbacks_->resetStream();
return;
Copy link
Member

Choose a reason for hiding this comment

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

Please don't add error handling for cases like this. A plain ASSERT is fine before proceeding. If something can't happen I would just assert it and move on. Same below. If we want to actually defend against bad cache implementations then I would remove the ASSERT(falses) statements throughout and actually handle things, and probably have stats eventually (so add a TODO for that).

Comment on lines +48 to +51
void CacheFilter::onDestroy() {
lookup_ = nullptr;
insert_ = nullptr;
}
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 add a small comment here that we assume that destroying the handles cancels all async callbacks, etc.?

namespace Cache {

class CacheFilterFactory
: public Common::FactoryBase<envoy::config::filter::http::cache::v2::CacheConfig> {
Copy link
Member

Choose a reason for hiding this comment

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

OK not sure what is going on here. I think @htuch is out this week so if this isn't burning urgent we should ask him next week before merging.

asctime
dechunk
dechunked
qdtext
Copy link
Member

Choose a reason for hiding this comment

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

I agree. There is already an issue tracking this which we should just implement in the checker.

@enozcan
Copy link

enozcan commented Feb 7, 2020

HI @toddmgreer,

Any complaints about the interfaces? Were they clear enough?

Overall everything was fine but I wonder a few things. I followed the design doc during implementation but it seems like out of date. Some updates are not reflected on the doc. If it is planned to be maintained, I can help to make it up-to-date by suggesting editions on the doc page. Also, as stated in the previous comments, vary headers issue is a little bit complicated. A sequence diagram for it just like the existing one in the doc might be extremely helpful for providers.

Also, in source/docs/cache_filter_plugins.md it's stated that:

If you write a new cache storage implementation, please add it to the Envoy
repository if possible.

Which directory should I address when including a new plugin in Envoy repository? May be a subdirectory like filters/http/cache/hazelcast_http_cache? Also the documentation for the plugin, is source/docs/ the right place?

@toddmgreer
Copy link
Contributor Author

toddmgreer commented Feb 7, 2020 via email

@toddmgreer
Copy link
Contributor Author

All of the changes in this PR have now been merged through other PRs, with the exception of support for multithreaded cache storage implementations (removed per reviewer request in #10019).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api no stalebot Disables stalebot from closing an issue waiting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants