Replies: 13 comments 1 reply
-
Hello @maetinee Please provide a self-executable example of the problem. |
Beta Was this translation helpful? Give feedback.
-
1st round request 3 requests (~5 sec send 1 request) and wait for timeout. My code
1st round log
2rd round log : if you see the sec time in log available first time is 4 and time is 18.29.54 (54 is sec) and available reset to 4 at time 18.30.21 (21 is sec) 27 sec after first request and in 1 min, I can send 9 request it over maximum that I set in rate limit.
|
Beta Was this translation helpful? Give feedback.
-
@maetinee provided information is not helpful enough for diagnosing. I need to view(and run) the code. You can start from ignoring JCache(and particular vendor) at all by using just a local bucket and mock clock. For example: package io.github.bucket4j;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class X {
public static void main(String[] args) {
AtomicLong currentTimeNanos = new AtomicLong();
TimeMeter ticker = new TimeMeter() {
@Override
public long currentTimeNanos() {
return currentTimeNanos.get();
}
};
Bucket bucket = Bucket4j.builder()
.addLimit(Bandwidth.classic(5, Refill.intervally(5, Duration.ofSeconds(60))))
.withCustomTimePrecision(ticker)
.build();
currentTimeNanos.set(TimeUnit.SECONDS.toNanos(7));
bucket.tryConsume(1);
System.out.println(TimeUnit.NANOSECONDS.toSeconds(currentTimeNanos.get()) + " - " +
bucket.getAvailableTokens());
currentTimeNanos.set(TimeUnit.SECONDS.toNanos(14));
bucket.tryConsume(1);
System.out.println(TimeUnit.NANOSECONDS.toSeconds(currentTimeNanos.get()) + " - " +
bucket.getAvailableTokens());
currentTimeNanos.set(TimeUnit.SECONDS.toNanos(21));
bucket.tryConsume(1);
System.out.println(TimeUnit.NANOSECONDS.toSeconds(currentTimeNanos.get()) + " - " +
bucket.getAvailableTokens());
currentTimeNanos.set(TimeUnit.SECONDS.toNanos(28));
bucket.tryConsume(1);
System.out.println(TimeUnit.NANOSECONDS.toSeconds(currentTimeNanos.get()) + " - " +
bucket.getAvailableTokens());
currentTimeNanos.set(TimeUnit.SECONDS.toNanos(35));
bucket.tryConsume(1);
System.out.println(TimeUnit.NANOSECONDS.toSeconds(currentTimeNanos.get()) + " - " +
bucket.getAvailableTokens());
}
} If you can not reproduce the problem via mocks but can reproduce via real code then provide it. Most likely in this case issue is related to JCache implementation vendor, anyway without a self-executable example I will not be able to help/ |
Beta Was this translation helpful? Give feedback.
-
ok thank |
Beta Was this translation helpful? Give feedback.
-
@vladimir-bukhtoyarov I tried mock this problem and I can reproduce via mocks. My mocks
My result
I try to update bucket-core and bucket4j-jcache to version 4.10.0. It have same problem. |
Beta Was this translation helpful? Give feedback.
-
@maetinee at the timepoint 100 lastRefillTime was set to 60 independently from the fact that it was passed 80 seconds between interactions. This is how Refill.intervally was designed to behave, in your example, you always have a fixed time window between refill 60, 120, 180, 240, 300, etc. So refilling up to 5 tokens at the time point 120 is legal according to the math model. If I understand correctly you were expected that the refill timepoints sequence should be reset because of long inactivity interval (between 20 and 100 has passed 80 seconds). Let me describe why current behavior is correct:
When you create |
Beta Was this translation helpful? Give feedback.
-
But if you still required in resetting the refill sequence after a long inactivity period then I can extend the intervally refill, in the way something like the following: public static Refill intervally(long tokens, Duration period, boolean resetRefillSequenceAfterLongInactivityPeriod) {
...
} I will be able to release it at weekends under the version 4.11.0 |
Beta Was this translation helpful? Give feedback.
-
@vladimir-bukhtoyarov thank you so mush |
Beta Was this translation helpful? Give feedback.
-
@vladimir-bukhtoyarov sorry, I don't sure about concept of this bucket. |
Beta Was this translation helpful? Give feedback.
-
To be more accurate: there is no resetting. There is a continuous refill that can be treated as a background process. |
Beta Was this translation helpful? Give feedback.
-
I am confused also about how bandwidth works. I created a very very simple bucket. Which accepts 3 requests every 60 seconds. But with this bucket, I am able to consume 5 times the bucket in 50 sec.
Resılt
|
Beta Was this translation helpful? Give feedback.
-
@ykalayy explanation is the same #128 (comment) |
Beta Was this translation helpful? Give feedback.
-
@vladimir-bukhtoyarov Yes I missed that. I got it very thanks for the explanation |
Beta Was this translation helpful? Give feedback.
-
I set rate limit 5 request / 1 min
but sometime I can sent request over maximum rate.
I log available tokens of bucket and I look something wrong.
Sometime (I wait 5 sec before 1 request) when pass 30sec avaliable token reset to 5 request but
I fix
Issue is how can I fix this issue because avaliable token of bucket should be reset when pass 1 min.
I use bucket-core and bucket4j-jcache version 4.0.1
This is some part of my log. I start first request is 15:11:39 avaliable is 5 and the last request is 15.12.08 (pass after first request 29 sec) but avaliable token is 5.
Beta Was this translation helpful? Give feedback.
All reactions