eozzy
eozzy

Reputation: 68760

Throttling / Rate Limiting in PHP

I'm using Amazon Product Advertising API which has a limit of 1 query per second. I found this library which seems to do what I want, but its a bit of an overkill for my requirement.

Is there a simpler way to rate limit (I'm calling a function) without using any libraries, besides using sleep because it would sleep for 1 second and the amount of requests I need to make, I should save each second.

$array = range(1,100);

foreach ($array as $value) {
    $timestamp = time();
    if ($timestamp != time()) {
        echo "\n value: ".$value." ".$timestamp;
    } else {
        usleep(1000000);
        echo "\n value: ".$value." ".$timestamp;
    }
}

Upvotes: 1

Views: 9887

Answers (3)

Markus Malkusch
Markus Malkusch

Reputation: 7878

You'll need shared state between your processes to share the rate as well. I suggest using my library: bandwidth-throttle/token-bucket

$storage  = new FileStorage(__DIR__ . "/api.bucket");
$rate     = new Rate(1, Rate::SECOND);
$bucket   = new TokenBucket(1, $rate, $storage);
$consumer = new BlockingConsumer($bucket);
$bucket->bootstrap(1);

// This will block all your processes to an effective rate of 1/s
$consumer->consume(1);

echo $productApi->doSomething();

Upvotes: 2

LIGHT
LIGHT

Reputation: 5712

$i=1;
foreach ($array as $value) {
    if($i==1) $timestamp = time();

    doYourThing();

    if($i==5){
        while ($timestamp == time()) { 
            continue;
        }
        $i=0;
    }
    $i++;
}

I modified @Horaland code to rate limit for 5 doYourThing() per second.

Upvotes: 1

Horaland
Horaland

Reputation: 897

Loop through your list of queries but on each loop get a unix timestamp (counts in seconds) and only send the query if the timestamp is higher than the last time you sent a query, then record the time stamp for checking in the next loop.

If your aim is to ensure that you don't send more that once a second but you don't want to waist seconds then a loop is probaly better than the if so:

foreach ($array as $value) {
  $timestamp = time();
  while ($timestamp == time()) { 
   continue;
  } 
  doYourThing();
}

so the script will loop through your list but for each item in the list it will continue spinning through the while loop until the second ticks over when it will execute your command and go straight into your next item.

Upvotes: 2

Related Questions