Blocking bucket creation
See original GitHub issueHi,
I am creating Bucket in Single Hazelcast instance serving two Application data centers (DC) and having custom waiting code to consumer the token as follows.
Creation:
Bandwidth limit = Bandwidth.classic(bucketSize, Refill.intervally(bucketSize, period));
Bucket bucket = Bucket4j.extension(Hazelcast.class).builder().addLimit(limit)
.build(hazelCastService.getBucketMap(), bucketId, RecoveryStrategy.RECONSTRUCT);
Consumption:
while (true) {
probe = getBucket().tryConsumeAndReturnRemaining(bucketBean.getTokenSize());
if (probe.isConsumed()) {
break;
} else {
Thread.sleep((long) (probe.getNanosToWaitForRefill() / 1000000.0));
}
}
But the issue is first data centers consumes token faster like three times higher than other one. So there is no equal distribution of tokens.
When application threads from both DCs sleeps till the refill and wakes-up, threads from first DC consumes faster than other one.
I am thinking it might be because custom handling of sleep and consume. Is this can be solved using “bucket.tryConsume(1, MAX_WAIT_NANOS, BlockingStrategy.PARKING)”, so that I dont need to handle sleep. And token might being served in the order when thread arrives.
Please suggest if this works…
When it is, then I am not finding method from Bucket object, its part of BlockingBucket object, but I cannot able to instantiate that object. please help.
Issue Analytics
- State:
- Created 5 years ago
- Comments:14
I do not use Hazelcast in my regular work, because GridGain is choosen, but integration of Bucket4j with Hazelcast is well tested by standard TCK that used for testing all distrubuted back-ends, the high-concurrent scenario is tested as well. Also JHipster uses Hazelcast with Bucket4j https://www.jhipster.tech/api-gateway/#rate_limiting and many other like spring-cloud-zuul-ratelimit, so I can make decision that integration of Bucket4j with Hazelcast has no obvious problems. Of course you should do testing by yourself and read this checklist.
If I understand correctly, you want to park the thread until tokens will be available, if so then avoid the manual parking/sleeping, it will never work fairy in concurrent environment. Instead you should use functionality which buil-it to library:
or
The difference between your code and built-in functionality is following:
Also I little bit worring about the
getBucket()
method, do not you cache the reference to the bucket? If not, then it is wrong, because creation the bucket on each request doubles the request rate to the Hazelcast server, one request to check that bucket exists and one request to do consumption request. If you are unable to cache the reference to bucket(for example because you do not know the amount of buckets that would be used), then you should use the ProxyManager as there https://github.com/vladimir-bukhtoyarov/bucket4j/blob/master/doc-pages/jcache-usage.md#example-1---limiting-access-to-http-server-by-ip-address ProxyManager solves the double request rate problem.@sarathbabur yes you are right, you found the right way.
Just use asScheduler method to get access to blocking functionality.