public function consume($tokens, &$seconds = 0)
{
try {
if ($tokens > $this->capacity) {
throw new \LengthException("Token amount ({$tokens}) is larger than the capacity ({$this->capacity}).");
}
if ($tokens <= 0) {
throw new \InvalidArgumentException("Token amount ({$tokens}) should be greater than 0.");
}
return $this->storage->getMutex()->synchronized(function () use($tokens, &$seconds) {
$tokensAndMicrotime = $this->loadTokensAndTimestamp();
$microtime = $tokensAndMicrotime["microtime"];
$availableTokens = $tokensAndMicrotime["tokens"];
$delta = $availableTokens - $tokens;
if ($delta < 0) {
$passed = microtime(true) - $microtime;
$seconds = max(0, $this->tokenConverter->convertTokensToSeconds($tokens) - $passed);
return false;
} else {
$microtime += $this->tokenConverter->convertTokensToSeconds($tokens);
$this->storage->setMicrotime($microtime);
$seconds = 0;
return true;
}
});
} catch (MutexException $e) {
throw new StorageException("Could not lock token consumption.", 0, $e);
}
}