bucket.asBlocking().tryConsume(t, Duration.ofSeconds(20)) sometimes does not wait #427
-
I am playing with this library and try to understand how I can use it. I wrote a simple restController in a SpringBoot app (see below) to try the basic operations on a bucket. I am especially interested in the tryConsume and addTokens combination. I was assuming the bucket.asBlocking().tryConsume(t, Duration.ofSeconds(20)) method would wait at least 20 seconds to see if a token becomes available (either from some process calling addToken, or a refillInterval happening). But I see cases where this method returns immediately with value false. With my example below, I call my 'consume' method 5 times and on 6th I get false (expected). What am I missing in my logic?
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
@PeterTeunissen hello,
As mentioneed in javadocs Also it needs to understand that if thread is became blocked, then it is guaranteed that this thread will consume requested tokens, no one thread can steal the tokens while thread is being parked, this is achived by reservation - consuming even if available tokens become less than zero. Try to run code bellow: import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
public class Example {
public static void main(String[] args) throws InterruptedException {
Bucket bucket = Bucket.builder()
.addLimit(limit -> limit.capacity(100).refillGreedy (10, Duration.ofSeconds(1)))
.build();
bucket = addListener(bucket);
while (true) {
int toConsume = ThreadLocalRandom.current().nextInt(99) + 1;
if (bucket.asBlocking().tryConsume(toConsume, Duration.ofSeconds(60))) {
System.out.println("Consumed " + toConsume + " tokens. Available " + bucket.getAvailableTokens() + " tokens.");
} else {
break;
}
}
}
private static Bucket addListener(Bucket bucket) {
return bucket.toListenable(new SimpleBucketListener() {
@Override
public void beforeParking(long nanos) {
System.out.println("Available tokens before parking " + bucket.getAvailableTokens() + ". Is going to be parked for " + TimeUnit.NANOSECONDS.toMillis(nanos) + " millis");
super.beforeParking(nanos);
}
});
}
} According to your code - it should return false in aproximatelly 1/3 (30-20/30) cases when trying in consume when no tokens. |
Beta Was this translation helpful? Give feedback.
@PeterTeunissen hello,
As mentioneed in javadocs
asBlocking().tryConsume()
operates only with refill time requires to close deficit. If it is known that specified waitThreshold is not enough to refill requested amount of tokens then it returnsfalse
imediatelly. Expectation thatasBlocking().tryConsume
interracts withaddToken
and wise versa, is not true.Also it needs to understand that if thread is became blocked, then it is guaranteed that this thread will cons…