limiting: Add Limiter #4
No reviewers
Labels
No labels
Infrastructure
blocked
bug
config
discussion
documentation
duplicate
enhancement
go
help wanted
internal
invalid
kludge
observability
perfomance
question
refactoring
wontfix
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: TrueCloudLab/frostfs-qos#4
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "a-savchuk/frostfs-qos:rps-limiting"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Added a
Limiter
to contol the number of concurrent operations. It can be used, for example, for active RPC limiting. It allows defining limits for both individual keys (e. g., RPC methods) and sets of keys (e. g., groups of RPC methods).25fffe99cd
toc99857c609
c99857c609
tod9bff390b5
d9bff390b5
to52deeef627
WIP: limiting: Add Limiterto limiting: Add Limiter@ -0,0 +35,4 @@
}
type Limiter struct {
m map[string]*semaphore
It's enough to acquire semaphore by two concurrent goroutines and we're on
panic
:)Why? This map is used only for reading
Yeah, okay. Then nevermind
I think it'd be good if I leave a comment about it
This PR is absolutely OK with me. But, let's be honest, the PR is introducing rather a semaphore than a limiter. It's just a naïve implementation of a rate-limiter. Here I suggest to discuss one thing: what if we introduce an interface
and make this implementation as
semaphoreLimiter
. Probably, we could also try some new implementation in the great future. For example, we could try softer way to limit a goroutine execution by getting it slept withtime.Sleep
etc.This is not change request, let's just discuss.
@dstepanov-yadro WDYT?
@ -0,0 +52,4 @@
type ReleaseFunc func()
func New(limits []KeyLimit) *Limiter {
lr := Limiter{m: make(map[string]*semaphore)}
Some kind of validation is needed. What happens if I specify two identical keys?
Done
@ -0,0 +5,4 @@
)
type semaphore struct {
ch chan struct{}
This option is generally good, but I have doubts that using channels is faster than
atomic
s. Please provide another comparison (benchmark) with theatomic
-based implementation.@dstepanov-yadro wrote in #4 (comment):
#4 (comment)
That's why I suggested to introduce an interface and try different implementations to compare
@aarifullin
Limiter
as an interface. After discussion with @dstepanov-yadro, left onlyTryAcquire
method and renamed it toAcquire
semaphoreLimiter
. Made it generic, so it can use different semaphore implementation, i. e. built with atomics, channels and etc.@dstepanov-yadro
52deeef627
to455fec9b99
455fec9b99
toae6938c61c
a1610ff987
to6e4a6d7610
6e4a6d7610
to6e59e9c285
6e59e9c285
toa37e3dc381
a37e3dc381
to730583b3bb
@ -0,0 +5,4 @@
)
type atomicSemaphore struct {
countDown atomic.Int64
countDown
->countdown
as it's one word :)Fixed
@ -0,0 +114,4 @@
sizes := []int64{1, 10, 100, 1000, 10000}
lockDurations := []time.Duration{0, time.Microsecond, 10 * time.Microsecond, 100 * time.Microsecond}
// sizes := []int64{1}
Leftovers?
Fixed
730583b3bb
tof7adcbb206
Excellent
f7adcbb206
to38482570f2
As discussed with @dstepanov-yadro, I left only atomic semaphore with burst allowed, also made it public to be reused later
38482570f2
to11ea76879b
@ -0,0 +11,4 @@
type Limiter interface {
// Acquire attempts to reserve a slot without blocking.
//
// Returns a release function and true if successful, otherwise false.
Shoul I call release func if
false
returned? Please, extend the doc.Done
@ -0,0 +23,4 @@
Release()
}
type semaphoreLimiter[T semaphore] struct {
To much abstractions:
semaphore
, generic type,BurstAtomic
, etc.Please, make the code simple.
Done
11ea76879b
tof2f98f6c2f
f2f98f6c2f
to51ff783b18
51ff783b18
to356851eed3
👍