-
Notifications
You must be signed in to change notification settings - Fork 0
feat: introduced custom rate limiter based on options pattern #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
aaronschweig
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some question and review suggestions
| func (r *StaticThenExponentialRateLimiter[T]) When(item T) time.Duration { | ||
| r.failuresLock.Lock() | ||
| defer r.failuresLock.Unlock() | ||
|
|
||
| now := r.clock.Now() | ||
|
|
||
| first, exists := r.firstAttempt[item] | ||
| if !exists { | ||
| first = now | ||
| r.firstAttempt[item] = first | ||
| } | ||
|
|
||
| timeSinceFirst := now.Sub(first) | ||
| if timeSinceFirst <= r.staticWindow { | ||
| return r.staticDelay | ||
| } | ||
|
|
||
| return r.exponential.When(item) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would appreciate a bit of a differentiation between the usage of read and write locks in here.
Especially since in this read case now, you are blocking the whole execution of other reads and writes. It would be good to only set the right type of lock where needed, and only set it as shortly as needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, thanks, it's done
|
|
||
| first, exists := r.firstAttempt[item] | ||
| if !exists { | ||
| first = now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not quite sure why this assignment is needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've double checked the logic, and updated it. Currently the rate limiter will return the static delay for the first run and this assignment is not needed anymore
|
|
||
| type StaticThenExponentialRateLimiter[T comparable] struct { | ||
| failuresLock sync.Mutex | ||
| firstAttempt map[T]time.Time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure I agree with the naming. I rather have something like staticAttempts or something similiar, as it cannot only hold the first attempt but rather as many attempts as needed until the staticWindow limitation is needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that we should only store the first attempt and then check how long it has been since the first attempt and if this time has reached the staticWindow duration, then we should fall into exponential backoff. Does this make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the implementation, I just don't like the naming 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, sorry, I misunderstood
On-behalf-of: SAP [email protected]
On-behalf-of: SAP [email protected]
|
I had also implemented rate limiting in a way less sophisticated way by back-porting what we did in metadata-operator in this branch: https://github.com/platform-mesh/golang-commons/tree/feat/rate-limiter and also applied it to our operator in a draft PR https://github.tools.sap/dxp/metadata-registry-operator/pull/1522 Not sure if we can join our forces or just skip mine in favor of what you are doing here. It is definitely better to have more options than my static time limiting approach :) |
On-behalf-of: SAP [email protected]
6dd7f00 to
dd78274
Compare
…olang-commons into feat/custom-rate-limiter On-behalf-of: SAP [email protected]
On-behalf-of: SAP [email protected]
On-behalf-of: SAP [email protected]
On-behalf-of: SAP [email protected]
On-behalf-of: SAP [email protected]
On-behalf-of: SAP [email protected]