You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Calling GetStatusCode() which will acquire a RLock in the function called by ExecOnLimitReached() will cause a deadlock on concurrent requests.
The deadlock is fairly easy to reproduce using the code below and a request generator like ab.
My use-case for calling GetStatusCode() in the function passed to SetOnLimitReached() is to increment a prometheus counter that had a label value for the status code being used.
Note this is a recursive lock issue where two rlocks are acquired, if a lock occurs between the two rlocks then there will be a deadlock.
// ExecOnLimitReached is thread-safe way of executing after-rejection function when limit is reached.func (l*Limiter) ExecOnLimitReached(w http.ResponseWriter, r*http.Request) {
l.RLock()
deferl.RUnlock()
fn:=l.onLimitReachediffn!=nil {
fn(w, r) // <--- any method calls that try to acquire a RLock() here will potentially cause a race
}
}
It should not be used for recursive read locking; a blocked Lock call excludes new readers from acquiring the lock. See the documentation on the RWMutex type.
Probably the simplest fix for this would be to constrain the Rlock() so it is around the read on l.onLimitReached
jarv
changed the title
Deadlock when calling GetStatusCode() status code in SetOnLimitReached()
Deadlock when calling GetStatusCode() in SetOnLimitReached()Oct 9, 2023
Calling
GetStatusCode()
which will acquire aRLock
in the function called byExecOnLimitReached()
will cause a deadlock on concurrent requests.The deadlock is fairly easy to reproduce using the code below and a request generator like
ab
.My use-case for calling
GetStatusCode()
in the function passed toSetOnLimitReached()
is to increment a prometheus counter that had a label value for the status code being used.code to reproduce:
and the following to generate load to cause the deadlock:
ab -n 2000 -c 50 http://localhost:6060/'
Full backtrace (condensed using panicparse):
The text was updated successfully, but these errors were encountered: