Fix race condition in specificRateLimiter

This commit is contained in:
Howl 2016-07-06 19:24:11 +02:00
parent faf948b037
commit 45d0de234b

View File

@ -1,6 +1,7 @@
package app package app
import ( import (
"fmt"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -51,15 +52,30 @@ func (s *specificRateLimiter) Request(u string, perMinute int) {
if !exists { if !exists {
c = makePrefilledChan(perMinute) c = makePrefilledChan(perMinute)
s.Mutex.Lock() s.Mutex.Lock()
s.Map[u] = c // Now that we have exclusive read and write-access, we want to
s.Mutex.Unlock() // make sure we don't overwrite an existing channel. Otherwise,
<-c // race conditions and panic happen.
go s.filler(u, perMinute) if cNew, exists := s.Map[u]; exists {
c = cNew
s.Mutex.Unlock()
} else {
s.Map[u] = c
s.Mutex.Unlock()
<-c
go s.filler(u, perMinute)
}
} }
<-c <-c
} }
func (s *specificRateLimiter) filler(el string, perMinute int) { func (s *specificRateLimiter) filler(el string, perMinute int) {
defer func() {
r := recover()
if r != nil {
fmt.Println(r)
}
}()
s.Mutex.RLock() s.Mutex.RLock()
c := s.Map[el] c := s.Map[el]
s.Mutex.RUnlock() s.Mutex.RUnlock()