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

feat(translator): implement ratelimit costs #5035

Merged
merged 12 commits into from
Jan 15, 2025

Conversation

mathetake
Copy link
Member

What type of PR is this?

The API implementation

What this PR does / why we need it:

This is the follow up on #4957 and implement the API.

Which issue(s) this PR fixes:
Fixes #4756

Release Notes: Yes

@mathetake mathetake requested a review from a team as a code owner January 11, 2025 02:01
@mathetake mathetake requested a review from zirain January 11, 2025 02:08
Copy link

codecov bot commented Jan 11, 2025

Codecov Report

Attention: Patch coverage is 87.80488% with 10 lines in your changes missing coverage. Please review.

Project coverage is 66.85%. Comparing base (da987da) to head (758f5f5).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/xds/translator/ratelimit.go 85.93% 7 Missing and 2 partials ⚠️
internal/xds/translator/httpfilters.go 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5035      +/-   ##
==========================================
+ Coverage   66.81%   66.85%   +0.03%     
==========================================
  Files         211      211              
  Lines       32854    32928      +74     
==========================================
+ Hits        21952    22014      +62     
- Misses       9579     9587       +8     
- Partials     1323     1327       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@zirain
Copy link
Member

zirain commented Jan 11, 2025

I think we have e2e for costPerReq, able to add one for costPreResponse?

@mathetake
Copy link
Member Author

can the e2e use the latest envoyproxy/ratelimit?

@zirain
Copy link
Member

zirain commented Jan 11, 2025

can the e2e use the latest envoyproxy/ratelimit?

IIRC, master branch always use the latest one.

@mathetake
Copy link
Member Author

ok cool

@arkodg
Copy link
Contributor

arkodg commented Jan 11, 2025

that was fast 😅

now that EG supports writing metadata via ext proc #5023 would be great if we can have an e2e where the ext proc inserts a fixed metadata that is used by the ratelimit API

@mathetake mathetake force-pushed the translation branch 2 times, most recently from 543c44e to ad5bf27 Compare January 11, 2025 17:58
@mathetake
Copy link
Member Author

mathetake commented Jan 11, 2025

2025-01-11T18:29:53.4823172Z         < X-Ratelimit-Remaining: 20

2025-01-11T18:29:53.4856372Z         < X-Ratelimit-Remaining: 18

2025-01-11T18:29:53.4884601Z         < X-Ratelimit-Remaining: 16

2025-01-11T18:29:53.4919980Z         < X-Ratelimit-Remaining: 14

looks like applyOnStreamDone is working fine but the per-descriptor is not working (both request and response costing 1 regardless of config)

@mathetake
Copy link
Member Author

from envoyproxy/envoy#37684:

added the per descriptor custom hits addend support (only for rate_limits in the RateLimitPerRoute for now).

maybe this is something to do with it

@mathetake
Copy link
Member Author

mathetake commented Jan 11, 2025

ok @arkodg looks like @wbpcode introduced the newRateLimitPerRoute used in type_per_filter_config vs the legacy existing rate limit config on route virtual_host.
image

and only the new one currently supports per-descriptor hits_addend

I think we have to either add support per-descriptor hits_addend to the legacy route/virtual_host config or migrate EG to use the new RateLimitPerRoute, which i think is not suitable as it will break the existing EG cluster (requiring the newest Envoy version)

@mathetake
Copy link
Member Author

i will take a look at the envoy code monday to see how hard to support them in the legacy config

@mathetake
Copy link
Member Author

I think it only requires to do some small refactoring...

@mathetake
Copy link
Member Author

envoyproxy/envoy#37972 this should fix the test

@mathetake
Copy link
Member Author

the required change in envoy seems a bit trickier than i thought... (the change itself is small but the build constraints by Envoy mobile makes it impossible as-is which in turn requires quite a refactoring around formatter...)

@arkodg
Copy link
Contributor

arkodg commented Jan 13, 2025

@mathetake can we copy the user defined metadata into the ratelimit hits addend metadata field using a filter instead, in a per route filter way ?

@mathetake
Copy link
Member Author

mathetake commented Jan 13, 2025

not sure what you meant but one workaround here is to use typed_per_filter_config RateLimitConfig instead of route-embedded-legacy rate limit only when costs are configured (which allows us to assume its latest Envoy) and i think that should work. Having said that though, I found the workaround in the envoyside and waiting for @wbpcode to review

@mathetake
Copy link
Member Author

ok tomorrow i will work on the workaround mentioned ^^

@mathetake
Copy link
Member Author

ok passing now!!!!!

@@ -662,6 +669,68 @@ var RateLimitHeadersAndCIDRMatchTest = suite.ConformanceTest{
},
}

var UsageRateLimitTest = suite.ConformanceTest{
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 is almost identical with the usecase with ai-gateway - except that the extproc sets the dynamic metadata on responseHeaders hook vs ai-gateway in responseBody hook. Either should work from Envoy pov as the response cost is applied when stream is closing

@mathetake
Copy link
Member Author

mathetake commented Jan 13, 2025

come on CI queue

@mathetake
Copy link
Member Author

ping @arkodg @zirain - passing now

@arkodg arkodg requested review from zhaohuabing and shawnh2 January 13, 2025 23:10
// patchRouteWithRateLimitOnTypedFilterConfig builds rate limit actions and appends to the route via
// the TypedPerFilterConfig field. This only happens when the response cost is specified which allows us to assume that
// users are using Envoy >= v1.33.0.
func patchRouteWithRateLimitOnTypedFilterConfig(route *routev3.Route, rateLimits []*routev3.RateLimit) error { //nolint:unparam
Copy link
Contributor

Choose a reason for hiding this comment

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

cc @zhaohuabing this introduces another design pattern to do per route filter 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.

yeah i was too lazy to do the right abstraction 😉

Copy link
Member Author

Choose a reason for hiding this comment

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

so anyways when we can set the floor Envoy version to v1.33, then we should be able to migrate to this typed_per_filter_config global rate limit unconditionally since that's the latest way (having support for per-descriptor-hits-addend) vs the current route-embedded config is legacy one

Copy link
Member

@zhaohuabing zhaohuabing Jan 14, 2025

Choose a reason for hiding this comment

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

Yeah, typed_per_filter_config is the way to go - it aligns with the approach used by all other filters for per-route configurations.

We can address htis in a seperate PR later.

@arkodg
Copy link
Contributor

arkodg commented Jan 14, 2025

@arkodg like this ? 8a016ba

hey @mathetake you'll also need to run make testdata to generate the IR

@mathetake
Copy link
Member Author

hmmm doesn't make any diff

@mathetake
Copy link
Member Author

mathetake commented Jan 14, 2025

@arkodg passing all tests modulo unrelated flake so can we merge?

@zhaohuabing
Copy link
Member

Look good. Fixed the conflicts then we can merge it.

@mathetake
Copy link
Member Author

/retest

Copy link
Contributor

@arkodg arkodg 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 !

@mathetake
Copy link
Member Author

come on

@mathetake
Copy link
Member Author

/retest

@mathetake
Copy link
Member Author

man the tests are too flaky 🤷 nothing to do with this PR

Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
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.

Usage based Rate Limiting (Counting from response header values)
4 participants