/** * Returns an infinite, traversable sequence that exponentially grows by given percentage * * @param integer $start * @param integer $percentage Integer between 1 and 100 * @return ExponentialSequence * @throws InvalidArgumentException */ function sequence_exponential($start, $percentage) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($start, 1, __METHOD__, 1); InvalidArgumentException::assertIntegerGreaterThanOrEqual($percentage, 1, __METHOD__, 2); InvalidArgumentException::assertIntegerLessThanOrEqual($percentage, 100, __METHOD__, 2); return new ExponentialSequence($start, $percentage); }
public function __construct($start, $amount) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($start, 0, __METHOD__, 1); InvalidArgumentException::assertInteger($amount, __METHOD__, 2); $this->start = $start; $this->amount = $amount; }
/** * Retry a callback until the number of retries are reached or the callback does no longer throw an exception * * @param callable $callback * @param integer $retries * @param Traversable|null $delaySequence Default: no delay between calls * @throws Exception Any exception thrown by the callback * @throws InvalidArgumentException * @return mixed Return value of the function */ function retry(callable $callback, $retries, Traversable $delaySequence = null) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($retries, 1, __FUNCTION__, 2); if ($delaySequence) { $delays = new AppendIterator(); $delays->append(new InfiniteIterator($delaySequence)); $delays->append(new InfiniteIterator(new ArrayIterator([0]))); $delays = new LimitIterator($delays, $retries); } else { $delays = array_fill_keys(range(0, $retries), 0); } $retry = 0; foreach ($delays as $delay) { try { return $callback($retry, $delay); } catch (Exception $e) { if ($retry === $retries - 1) { throw $e; } } if ($delay > 0) { usleep($delay); } ++$retry; } }
public function __construct($start, $percentage) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($start, 1, __METHOD__, 1); InvalidArgumentException::assertIntegerGreaterThanOrEqual($percentage, 1, __METHOD__, 2); InvalidArgumentException::assertIntegerLessThanOrEqual($percentage, 100, __METHOD__, 2); $this->start = $start; $this->percentage = $percentage; }
/** * Retry a callback until it returns a truthy value or the timeout (in microseconds) is reached * * @param callable $callback * @param integer $timeout Timeout in microseconds * @param Traversable|null $delaySequence Default: no delay between calls * @throws InvalidArgumentException * @return boolean */ function poll(callable $callback, $timeout, Traversable $delaySequence = null) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($timeout, 0, __FUNCTION__, 2); $retry = 0; $delays = new AppendIterator(); if ($delaySequence) { $delays->append(new InfiniteIterator($delaySequence)); } $delays->append(new InfiniteIterator(new ArrayIterator([0]))); $limit = microtime(true) + $timeout / 100000; foreach ($delays as $delay) { $value = $callback($retry, $delay); if ($value) { return $value; } if (microtime(true) > $limit) { return false; } if ($delay > 0) { usleep($delay); } ++$retry; } }
/** * Returns an infinite, traversable sequence that linearly grows by given amount * * @param integer $start * @param integer $amount * @return Traversable */ function sequence_linear($start, $amount) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($start, 0, __FUNCTION__, 1); InvalidArgumentException::assertInteger($amount, __FUNCTION__, 2); return new LinearSequence($start, $amount); }
/** * Returns an infinite, traversable sequence of constant values * * @param integer $value * @return Traversable */ function sequence_constant($value) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($value, 0, __FUNCTION__, 1); return new InfiniteIterator(new ArrayIterator([$value])); }