Fix race condition in specificRateLimiter
This commit is contained in:
		@@ -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()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user