-
Notifications
You must be signed in to change notification settings - Fork 458
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
API Refactor: Rate-limiting middleware plus scaffolding #1563
Conversation
- Middleware interface provides pre and post processing steps - Provides interceptor implemementations for gRPC - Implements logger middleware - Implements per-rpc and per-caller rate limiting Signed-off-by: Andrew Harding <andrew.harding@hpe.com>
Signed-off-by: Andrew Harding <andrew.harding@hpe.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good!
Adding more test coverage is intended to be addressed separately, right?
) | ||
|
||
var ( | ||
// NewRateLimiter is used to create a new ratelimiter. It returns a limiter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// NewRateLimiter is used to create a new ratelimiter. It returns a limiter | |
// newRawRateLimiter is used to create a new ratelimiter. It returns a limiter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Burst() int | ||
} | ||
|
||
// NoLimit returns a rate limiter does not rate limit. It is used to configure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// NoLimit returns a rate limiter does not rate limit. It is used to configure | |
// NoLimit returns a rate limiter that does not rate limit. It is used to configure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
// WithRateLimits returns a middleware that performs rate limiting for the | ||
// group of methods descripted by the rateLimits map. It provides the | ||
// configured rate limiter to the method handlers via the request context. If | ||
// the middleware is invoked for a method is not described in the map, it will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// the middleware is invoked for a method is not described in the map, it will | |
// the middleware is invoked for a method that is not described in the map, it will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
lim.mtx.RUnlock() | ||
return limiter | ||
} | ||
lim.mtx.RUnlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not call defer lim.mtx.Unlock()
right after lim.mtx.RLock()
? at the beginning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would cause a deadlock below where this function takes the write lock to create a new limiter under this address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it.
} | ||
|
||
type rateLimitsMiddleware struct { | ||
limiters map[string]api.RateLimiter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be accessed concurrently? should we have a mutex?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be mutated after passing it into rate limits, so concurrent access should be safe. I'll document the intended ownership on the WithRateLimits
call.
Yep, there is some unit-test coverage around middleware and stuff that is required. I'll have those in follow up PRs. This also doesn't cover pruning the per-ip limit map. I've added a TODO and will implement that as well. |
Signed-off-by: Andrew Harding <andrew.harding@hpe.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
** Update ** This PR does not handle periodic pruning of the per-ip limiter map. It also doesn't have direct unit-tests for the middleware chaining, etc. These will come in follow up PRs.