type Ratelimiter struct {
mutex sync.RWMutex
- stop chan struct{}
+ stopReset chan struct{}
tableIPv4 map[[net.IPv4len]byte]*RatelimiterEntry
tableIPv6 map[[net.IPv6len]byte]*RatelimiterEntry
}
rate.mutex.Lock()
defer rate.mutex.Unlock()
- if rate.stop != nil {
- close(rate.stop)
+ if rate.stopReset != nil {
+ close(rate.stopReset)
}
}
// stop any ongoing garbage collection routine
- if rate.stop != nil {
- close(rate.stop)
+ if rate.stopReset != nil {
+ close(rate.stopReset)
}
- rate.stop = make(chan struct{})
+ rate.stopReset = make(chan struct{})
rate.tableIPv4 = make(map[[net.IPv4len]byte]*RatelimiterEntry)
rate.tableIPv6 = make(map[[net.IPv6len]byte]*RatelimiterEntry)
go func() {
ticker := time.NewTicker(time.Second)
+ ticker.Stop()
for {
select {
- case <-rate.stop:
+ case _, ok := <-rate.stopReset:
ticker.Stop()
- return
+ if ok {
+ ticker = time.NewTicker(time.Second)
+ } else {
+ return
+ }
case <-ticker.C:
func() {
rate.mutex.Lock()
}
entry.mutex.Unlock()
}
+
+ if len(rate.tableIPv4) == 0 && len(rate.tableIPv6) == 0 {
+ ticker.Stop()
+ }
}()
}
}
rate.mutex.Lock()
if IPv4 != nil {
rate.tableIPv4[keyIPv4] = entry
+ if len(rate.tableIPv4) == 1 && len(rate.tableIPv6) == 0 {
+ rate.stopReset <- struct{}{}
+ }
} else {
rate.tableIPv6[keyIPv6] = entry
+ if len(rate.tableIPv6) == 1 && len(rate.tableIPv4) == 0 {
+ rate.stopReset <- struct{}{}
+ }
}
rate.mutex.Unlock()
return true