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

Add inbound rate limiting #722

Merged
merged 2 commits into from
Oct 26, 2021
Merged

Add inbound rate limiting #722

merged 2 commits into from
Oct 26, 2021

Conversation

embano1
Copy link
Member

@embano1 embano1 commented Oct 11, 2021

WIP, first proposal up for discussion to implement inbound rate limiting.

Features/Behavior:

  • Applied in ServeHTTP, i.e. cannot be bypassed
  • Interface, i.e. bring your own via HTTP Option
  • Defaults to no rate limiting via noOpLimiter to keep current behavior, even though we have been advertising a magic number 1000 when asked for in HTTP options

See #59 for more context.

Closes: #59
Signed-off-by: Michael Gasch mgasch@vmware.com

Copy link
Contributor

@benmoss benmoss left a comment

Choose a reason for hiding this comment

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

Looks great to me!

v2/protocol/http/protocol.go Outdated Show resolved Hide resolved
@benmoss
Copy link
Contributor

benmoss commented Oct 13, 2021

cc @n3wscott

@embano1
Copy link
Member Author

embano1 commented Oct 14, 2021

Thx for the feedback @benmoss. Once Scott gets a chance to review I'll incorporate any changes and fix the outstanding TODO items, e.g. docs.

type RateLimiter interface {
// Take attempts to take one token from the rate limiter for the specified
// request. It returns ok when this operation was successful. In case ok is
// false, reset will indicate the time in seconds when it is safe to perform
Copy link
Member

Choose a reason for hiding this comment

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

reset seems like it should not be unit seconds, but nanoseconds

Copy link
Member

Choose a reason for hiding this comment

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

oh I see, it is because of https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After is unit seconds.

I still feel like unit seconds is too large of a unit. hmmm

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, rational for secs. Even if a rate limiter internally would use sub-sec precision, IMHO the result should just be (rounded) sec so we don't have to do additional conversion in the handler.

v2/protocol/http/protocol.go Outdated Show resolved Hide resolved
v2/protocol/http/protocol.go Outdated Show resolved Hide resolved
// false, reset will indicate the time in seconds when it is safe to perform
// another attempt. An error is returned when this operation failed, e.g. due to
// a backend error.
Take(ctx context.Context, r *http.Request) (ok bool, reset uint64, err error)
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
Take(ctx context.Context, r *http.Request) (ok bool, reset uint64, err error)
Allow(ctx context.Context, r *http.Request) (ok bool, after uint64, err error)

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 changed the type of r to be a string, we could extract the target host in the http side and then also use this interface at the overall level, perhaps even let us limit at the client send level if we wanted to. The r becomes bucket string and you could configure it to be any thing you want.

Copy link
Member Author

@embano1 embano1 Oct 22, 2021

Choose a reason for hiding this comment

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

So just to understand (since I had string in a first iteration): which value would we pass then from req into the string of the rate limiter interface in ServeHTTP? If we hardcode to target (source?) host, we lose bucketing options on other req properties, no?

Closes: cloudevents#59
Signed-off-by: Michael Gasch <mgasch@vmware.com>
@embano1 embano1 changed the title WIP: Add inbound rate limiting Add inbound rate limiting Oct 25, 2021
@embano1
Copy link
Member Author

embano1 commented Oct 25, 2021

/hold until question on which value to pass to limiter interface is clarified (will squash merge afterwards too)

Signed-off-by: Michael Gasch <mgasch@vmware.com>
Copy link
Member

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

@n3wscott n3wscott merged commit 5d1b173 into cloudevents:main Oct 26, 2021
@embano1 embano1 deleted the issue-59 branch October 26, 2021 17:58
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.

[Webhook] Implement Allowed Rate
3 participants