diff --git a/README.md b/README.md index b94c8bf1..9bac3f3a 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,9 @@ use any of them: com.github.vladimir-bukhtoyarov bucket4j-core - 4.1.1 + 4.1.2 -``` -***Warning:*** do not use ```4.1.0``` version, it was released with mistake. +``` #### You can build Bucket4j from sources ```bash git clone https://github.com/vladimir-bukhtoyarov/bucket4j.git diff --git a/bucket4j-benchmarks/pom.xml b/bucket4j-benchmarks/pom.xml index 2746ee1e..eb4f3549 100644 --- a/bucket4j-benchmarks/pom.xml +++ b/bucket4j-benchmarks/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent bucket4j-benchmarks diff --git a/bucket4j-core/pom.xml b/bucket4j-core/pom.xml index 5e529a3e..9ddb19a5 100644 --- a/bucket4j-core/pom.xml +++ b/bucket4j-core/pom.xml @@ -23,7 +23,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent 4.0.0 diff --git a/bucket4j-core/src/main/java/io/github/bucket4j/BucketState.java b/bucket4j-core/src/main/java/io/github/bucket4j/BucketState.java index 3c59acb9..02b94d3d 100644 --- a/bucket4j-core/src/main/java/io/github/bucket4j/BucketState.java +++ b/bucket4j-core/src/main/java/io/github/bucket4j/BucketState.java @@ -198,11 +198,11 @@ private long calculateDelayNanosAfterWillBePossibleToConsume(int bandwidthIndex, if (bandwidth.refillIntervally) { return calculateDelayNanosAfterWillBePossibleToConsumeForIntervalBandwidth(bandwidthIndex, bandwidth, deficit, currentTimeNanos); } else { - return calculateDelayNanosAfterWillBePossibleToConsumeForGreedyBandwidth(bandwidth, deficit); + return calculateDelayNanosAfterWillBePossibleToConsumeForGreedyBandwidth(bandwidthIndex, bandwidth, deficit); } } - private long calculateDelayNanosAfterWillBePossibleToConsumeForGreedyBandwidth(Bandwidth bandwidth, long deficit) { + private long calculateDelayNanosAfterWillBePossibleToConsumeForGreedyBandwidth(int bandwidthIndex, Bandwidth bandwidth, long deficit) { long refillPeriodNanos = bandwidth.refillPeriodNanos; long refillPeriodTokens = bandwidth.refillTokens; long divided = multiplyExactOrReturnMaxValue(refillPeriodNanos, deficit); @@ -211,6 +211,8 @@ private long calculateDelayNanosAfterWillBePossibleToConsumeForGreedyBandwidth(B // there is no sense to stay in integer arithmetic when having deal with so big numbers return (long)((double) deficit / (double)refillPeriodTokens * (double)refillPeriodNanos); } else { + long correctionForPartiallyRefilledToken = getRoundingError(bandwidthIndex); + divided -= correctionForPartiallyRefilledToken; return divided / refillPeriodTokens; } } diff --git a/bucket4j-core/src/test/java/io/github/bucket4j/BucketRoundingRulesSpecification.groovy b/bucket4j-core/src/test/java/io/github/bucket4j/BucketRoundingRulesSpecification.groovy index f0df6d6a..0e1d3742 100644 --- a/bucket4j-core/src/test/java/io/github/bucket4j/BucketRoundingRulesSpecification.groovy +++ b/bucket4j-core/src/test/java/io/github/bucket4j/BucketRoundingRulesSpecification.groovy @@ -17,8 +17,10 @@ package io.github.bucket4j +import io.github.bucket4j.mock.BucketType import io.github.bucket4j.mock.TimeMeterMock import spock.lang.Specification +import spock.lang.Unroll import java.time.Duration @@ -66,4 +68,27 @@ class BucketRoundingRulesSpecification extends Specification { !bucket.tryConsume(1) } + @Unroll + def "Partially refilled token should not be missed when calculating time for refill #bucketType"(BucketType bucketType) { + expect: + def timeMeter = new TimeMeterMock(0) + def builder = Bucket4j.builder() + .addLimit(Bandwidth.simple(1, Duration.ofSeconds(1))) + Bucket bucket = bucketType.createBucket(builder, timeMeter) + + assert bucket.tryConsumeAsMuchAsPossible() == 1 + + timeMeter.addTime(200_000_000) + + ConsumptionProbe probe1 = bucket.tryConsumeAndReturnRemaining(1) + assert !probe1.consumed + assert probe1.nanosToWaitForRefill == 800_000_000 + + ConsumptionProbe probe2 = bucket.tryConsumeAndReturnRemaining(3) + assert !probe2.consumed + assert probe2.nanosToWaitForRefill == 2_800_000_000 + where: + bucketType << BucketType.values() + } + } diff --git a/bucket4j-hazelcast/pom.xml b/bucket4j-hazelcast/pom.xml index 8b07b9e9..af68a1c4 100644 --- a/bucket4j-hazelcast/pom.xml +++ b/bucket4j-hazelcast/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent bucket4j-hazelcast diff --git a/bucket4j-ignite/pom.xml b/bucket4j-ignite/pom.xml index 17857190..1934bd4a 100644 --- a/bucket4j-ignite/pom.xml +++ b/bucket4j-ignite/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent bucket4j-ignite diff --git a/bucket4j-infinispan-8/pom.xml b/bucket4j-infinispan-8/pom.xml index 597a1fc1..df560676 100644 --- a/bucket4j-infinispan-8/pom.xml +++ b/bucket4j-infinispan-8/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent diff --git a/bucket4j-infinispan/pom.xml b/bucket4j-infinispan/pom.xml index a7d48829..91f76ddf 100644 --- a/bucket4j-infinispan/pom.xml +++ b/bucket4j-infinispan/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent diff --git a/bucket4j-jcache/pom.xml b/bucket4j-jcache/pom.xml index 7d385a89..9f02cf3e 100644 --- a/bucket4j-jcache/pom.xml +++ b/bucket4j-jcache/pom.xml @@ -23,7 +23,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent 4.0.0 diff --git a/bucket4j-parent/pom.xml b/bucket4j-parent/pom.xml index 4663e563..beb6172b 100644 --- a/bucket4j-parent/pom.xml +++ b/bucket4j-parent/pom.xml @@ -23,7 +23,7 @@ 4.0.0 com.github.vladimir-bukhtoyarov - 4.2.0 + 4.2.1 bucket4j-parent pom bucket4j-parent diff --git a/experimental/bucket4j-mysql/pom.xml b/experimental/bucket4j-mysql/pom.xml index 3321afff..09470e69 100644 --- a/experimental/bucket4j-mysql/pom.xml +++ b/experimental/bucket4j-mysql/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../../bucket4j-parent bucket4j-mysql diff --git a/experimental/bucket4j-postgresql/pom.xml b/experimental/bucket4j-postgresql/pom.xml index 33e95a66..5a93106c 100644 --- a/experimental/bucket4j-postgresql/pom.xml +++ b/experimental/bucket4j-postgresql/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../../bucket4j-parent bucket4j-postgresql diff --git a/experimental/bucket4j-redis/pom.xml b/experimental/bucket4j-redis/pom.xml index f88caebf..372221ee 100644 --- a/experimental/bucket4j-redis/pom.xml +++ b/experimental/bucket4j-redis/pom.xml @@ -24,7 +24,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../../bucket4j-parent bucket4j-redis diff --git a/experimental/pom.xml b/experimental/pom.xml index a85fef8a..a3da27e7 100644 --- a/experimental/pom.xml +++ b/experimental/pom.xml @@ -22,7 +22,7 @@ com.github.vladimir-bukhtoyarov bucket4j-parent - 4.2.0 + 4.2.1 ../bucket4j-parent 4.0.0 diff --git a/pom.xml b/pom.xml index e7607bca..48cf983f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ com.github.vladimir-bukhtoyarov bucket4j - 4.2.0 + 4.2.1 pom bucket4j