Closed jinwik closed 2 years ago
@jinwik I'd be open to that, but a better solution might be to support non-blocking rate limiting in general (#318), which I'm actually working on right now. I think this would accomplish what you want, since it would use whatever Scheduler
you configure (like a vertx scheduler) to perform the rate limit waiting.
@jinwik #318 is implemented in master now if you want to give it a try. I'll likely cut a release in the next day or two.
@jhalterman Great, I'll give it a try, thx
3.2 is released which includes #318, so async waiting on rate limiters should be working now. Feel free to leave a comment and re-open if things aren't working as expected.
we can use a custom scheduler to avoid blocking vertx eventloop, but I need to get the actual delay time and record it in the http response header.
It is easier if acquirePermitWaitNanos
is public, e.g:
// HTTP request
RoutingContext routingContext = ...
long ms = toMs(rateLimiterSingleton.acquirePermitWaitNanos());
if(ms >= 1) {
vertx.setTimer(ms, l -> {
routingContext.response().putHeader("delay", ms);
routingContext.response().end(body);
});
}
//...
@jinwik Can you give me a bit of a broader example how you're using Vert.x with failsafe? I was assuming you were using a custom Failsafe scheduler, something like this:
If you implement a Scheduler
similar to that, then Failsafe will pass runnables to the scheduler when it needs to wait for something, like a RateLimiter.
Thanks @jinwik. It looks like it makes sense to just expose the wait time. I'll push a change for that shortly which should be in the next release.
I'm curious though, is the custom "delay" header something special for your setup, or do you think something like that is common with other usages of a RateLimiter with vertx?
Thanks, @jhalterman, the custom "delay" header is my special case.
Support for RateLimiter.reservePermit()
, tryReservePermit(Duration)
, and similar methods, has been released in 3.2.1:
Thanks a lot @jhalterman
No problem. I forgot to mention, since you want to wait on a permit externally rather than going through a Failsafe execution (get, getAsync, etc) you'll need to use the RateLimiter in a standalone way. Ex:
RateLimiter<Object> rateLimiter = RateLimiter.smoothBuilder(1, Duration.ofSeconds(1));
Duration permitWaitTime = rateLimiter.tryReservePermit(Duration.ofSeconds(10));
if (permitWaitTime.toNanos() > -1)
vertx.setTimer....
If you want to also record execution results and check for completion, you can use a standalone execution object. Let me know if you run into any trouble with your use case.
Is possible to add a new method to RateLimiter, like
long reservePermission()
(like resilience4j) , which returns waiTimeInNanos, so we can use vertx.setTimer to wait, instead ofThread.sleep
(which will bock the eventloop), thx.