New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic configuration of capacity #76
Comments
Dynamic capacity was removed because of contradiction with other features. Currently there are no direct alternative. replaceConfiguration method is single way to change capacity |
Thanks for prompt answer. Do you suggest to keep 24 unique buckets per hour as alternative solution otherwise hour of duration has to be checked on every request to call replaceConfiguration before request is served. Please let me know your thoughts. |
@nitenA splitting to 24 buckets is unpractical because each bucket has own independent state, so there is a chance of over-consumption near to border of hour , because next bucket is not mentioned about amount of tokens that issued by previous bucket. Try to think about problem in different way. I want to speculate that for mostly cases dynamic capacity can be emulated by dynamic weight of tokens. This example from bucket4j-1.0 can be directly emulated without any lost of user experience with Firstly, create bucket with maximum capacity that proposed to be: LocalBucket bucket = Bucket4j.builder()
.addLimit(Bandwidth.simple(10, Duration.ofMinutes(1)))
.build(); Secondly, when consuming just multiply tokens if neccessary: private static boolean tryConsume(Bucket bucket, int tokens) {
int weightedTokens;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour >= 7 && hour <= 23) {
weightedTokens = tokens;
} else {
// at night tokens are more costly
weightedTokens = tokens * 5;
}
return bucket.tryConsume(weightedTokens);
} |
Hi @vladimir-bukhtoyarov
just for ex, 12 am -8 am ---> bucket (Bandwidth.simple(10, Duration.ofMinutes(1)))
|
Sorry if i was unclean, but i try to insist again that all you need already present in library.
If duration is fixed(as in your case when duration is 1 minute), then solving your task is trivial:
Lets do this exerciser together:
public int getWeight(int tokens) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour < 9) {
return 40/10*tokens
} else if (hour < 14) {
return 40/5*tokens
} else if (hour >= 21) {
return 40/2*tokens
} else {
return 40/8*tokens
}
} |
thanks @vladimir-bukhtoyarov for detailed explanation. |
One last question. When we use weighted bucket, the bucket will be created with max capacity like you mentioned.. In our case, what will be the ideal BucketConfgiuration? I am using Refill.intervally to turn of greediness. Just to reiterate we don't want to go above capacity which is fixed for defined duration i.e. 1 minute. To make it clear, let's go with your suggestion. For 12 am -8 am if i need to have 10 tokens per min (fixed), having below configuration doesn't produce right results. I tried tryConsume(4) to utilize weighted token but doesn't get desired results. Refill refill = Refill.intervally(10, Duration.ofMinutes(1)); As now you understand my problem and i understand weighted token concept, only remaining thing to decide right Bucket Configuration for fixed token per minute. Pls suggest |
I think below is right configuration for me which works fine.. Overall capacity and refill should be same and having Refill.intervally shutting of greediness. Just validate.. Refill newRefill = Refill.intervally(40, Duration.ofMinutes(1)); |
@nitenA you are right, tokens of refill should be multiplied similar to capacity. |
Thanks for all your help. |
Hi,
This is in reference to old issue #45 where i would like to create dynamic capacity per hour.
Earlier version has concept of BandwidthAdjuster which kind of I am looking for. Not sure if it actually adjust bucket during run time when hour changes as feature has been decommissioned so can't test.
Can you suggest any alternative way to achieve below using new 4.* version of Bucket4J?
BandwidthAdjuster adjuster = new BandwidthAdjuster() {
@OverRide
public long getCapacity(long currentTime) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(currentTime);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour >= 7 && hour <= 23) {
return 10;
} else {
return 2;
}
}
};
Buckets.withMillisTimePrecision()
.withLimitedBandwidth(adjuster, TimeUnit.MINUTES, 1, 10);
The text was updated successfully, but these errors were encountered: