Reputation: 55
I use https://github.com/bandwidth-throttle/token-bucket for queries limited to the external server. My code:
function main() {
unlink(__DIR__ . "/api.bucket2");
$storage = new FileStorage(__DIR__ . "/api.bucket2");
$rate = new Rate(3, Rate::SECOND);
$bucket = new TokenBucket(3, $rate, $storage);
$bucket->bootstrap(3);
$consumer = new BlockingConsumer($bucket);
for ($i = 0; $i < 12; $i++) {
$consumer->consume(1);
work();
}
}
function work() {
echo date("d.m.Y H:i:s") . substr((string)microtime(), 1, 4) . "\n";
}
main();
Result:
-bash-4.2$ php -f worker-test.php
03.05.2016 14:26:16.785
03.05.2016 14:26:16.785
03.05.2016 14:26:16.786
03.05.2016 14:26:17.118
03.05.2016 14:26:17.451
03.05.2016 14:26:17.784
...
I expected that the function will be called 3 times per second, but it is not. First 6 calls was in 1 second. if I change "$bucket->bootstrap(3); " on "$bucket->bootstrap(0);", it will be better:
03.05.2016 14:33:34.913
03.05.2016 14:33:35.245
03.05.2016 14:33:35.578
03.05.2016 14:33:35.911
...
but it is still more than 3 per second. What am I doing wrong?
Upvotes: 1
Views: 532
Reputation: 7878
$bucket->bootstrap(3);
TokenBucket::bootstrap(3)
puts three initial tokens into the bucket. Those initial tokens can be consumed instantly. You effectively don't throttle the rate for those first calls.
If you don't want that initial burst, you did correctly bootstrap without any tokens.
03.05.2016 14:33:34.913 03.05.2016 14:33:35.245 03.05.2016 14:33:35.578 03.05.2016 14:33:35.911
but it is still more than 3 per second.
I count 3 per second. Please tolerate this observed variance of ±1ms. In the long run you'll get in average 3 per second.
This ±1ms comes probably from this implementation detail of BlockingConsumer
:
// sleep at least 1 millisecond.
usleep(max(1000, $seconds * 1000000));
Upvotes: 2