Comments (5)
Right now to have something like this that doesnt allow bursts to pass by, there is this poor man's option (and likely also naive) which is something managed outside the lib:
- have a single rate limiter for normal ops
- when an increase/decrease is requested, create a second rate limiter with the new value. We enter "swapping mode"
Take
now takes from both rate limiters in either serial or parallel fashion (not sure about which has better correctness here yet)- When the window of the first (old) rate limiter is expired, remove it (we need to track windows here)
- We are back at having a single rate limiter
- The swapping mode is done, allowing more calls to increase/decrease again. Any calls to increase/decrease that were done while we were in swapping mode either got rejected, waiting (blocked) or executed later (async)
from ratelimit.
Generally seems plausible, but as I commented in the other task, I don't expect to have bandwidth to work on this soon.
However, reading your use-case, I'm not sure if updating limits on the fly would make sense - it seems like you want some kind of burst++ mode, rather than external limits?
Note to self: #69 was asking for the same feature.
from ratelimit.
you can wrap it, and use a block channel to stop the rate limit
func (rl *RateLimit) Take() time.Time {
<-rl.blockSignal
return rl.throttle.Take()
}
from ratelimit.
Hi, I know I must be missing something here 😓
Why can't we have something like this to achieve the same goal ?
type Limiter struct {
limiter ratelimit.Limiter
mutex sync.RWMutex
}
func NewLimiter(cfg config) Limiter {
return Limiter{limiter: ratelimit.New(cfg.LimiterOperations, ratelimit.Per(cfg.LimiterDuration))}
}
func (l *Limiter) Update(ops int, duration time.Duration) {
l.mutex.Lock()
defer l.mutex.Unlock()
l.limiter = ratelimit.New(ops, ratelimit.Per(duration))
}
func (l *Limiter) Take() time.Time {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.limiter.Take()
}
As far as I could see, we could update the limiter while calling limiter.Take()
from different go routines without any issue
time.AfterFunc(time.Second*5, func() {
limiter.Update(3, time.Second)
})
time.AfterFunc(time.Second*10, func() {
limiter.Update(20, time.Second)
})
time.AfterFunc(time.Second*15, func() {
limiter.Update(100, time.Second)
})
from ratelimit.
Sorry, we don't foresee adding this to the library - contrary to your example, replacing the limit on the fly has non-obvious behavior wrt already existing limits and slack. Additionally, the extra lock defeats the purpose of the lock-less implementation we have.
Since, however, as your example shows it is simple enough to wrap this in your own code. We would encourage you to do just that if that fits your requirements.
from ratelimit.
Related Issues (20)
- X-Rate-Limit
- this line of doc is wrong
- When one of my operations has not called the atomicInt64Limiter.task() function for a long time, the speed limit may fail to be called again HOT 1
- change limit after start HOT 1
- Release all recent changes with a new v0.3.0 tag. HOT 1
- Unexpected results on CI with higher loop iterations
- This is rate shaping, not limiting HOT 1
- Take always return without block if it enters the case branch HOT 3
- [Docs] Need to illustrate the option `Slack` HOT 6
- The "slack" option doesn't make effect when use newAtomicInt64Based version rate limit
- Behavior of take in goroutine HOT 1
- benbjohnson/clock is out of date HOT 1
- context.Context support for Take? HOT 7
- If add some check in New function?
- What's the major diff v.s. https://pkg.go.dev/golang.org/x/time/rate HOT 1
- Adding support for an `Allow` method HOT 10
- Why does the example_test fail when I run it locally? HOT 2
- atomicInt64Limiter WithoutSlack doesn't block HOT 18
- Can you support the take method of non blocking sleep
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ratelimit.