mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
Refactor `ratelimit.acquire()` to properly enforce the *globalMaxConn* limit.
This commit is contained in:
parent
85e2d886bc
commit
895471afa1
@ -37,8 +37,11 @@ type rateLimit struct {
|
||||
// channel this is in-turn used to rate limit incoming connections in
|
||||
// ServeHTTP() http.Handler method.
|
||||
func (c *rateLimit) acquire() error {
|
||||
//lock access to enter waitQueue
|
||||
c.lock.Lock()
|
||||
// Kick out clients when it is really crowded
|
||||
if len(c.waitQueue) == cap(c.waitQueue) {
|
||||
defer c.lock.Unlock() //unlock after return
|
||||
return errTooManyRequests
|
||||
}
|
||||
|
||||
@ -46,11 +49,15 @@ func (c *rateLimit) acquire() error {
|
||||
// wanting to process their requests
|
||||
c.waitQueue <- struct{}{}
|
||||
|
||||
// Moving from wait to work queue is protected by a mutex
|
||||
// to avoid draining waitQueue with multiple simultaneous clients.
|
||||
c.lock.Lock()
|
||||
c.workQueue <- <-c.waitQueue
|
||||
// Unlock now. If we unlock before sending to the waitQueue
|
||||
// channel, we can have multiple go-routines blocked on
|
||||
// sending to the waitQueue (and exceeding the max. number of
|
||||
// waiting connections.)
|
||||
c.lock.Unlock()
|
||||
|
||||
// Block to put a waiting go-routine into processing mode.
|
||||
c.workQueue <- <-c.waitQueue
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user