(int >= 0), 'nanos' => (int >= 0)] specifying how * long an operation should pause before retrying. Should accept a * single argument of type `\Exception`. * @param callable $retryFunction [optional] returns bool for whether or not * to retry. */ public function __construct($retries, callable $delayFunction, callable $retryFunction = null) { $this->retries = $retries !== null ? (int) $retries : 3; $this->delayFunction = $delayFunction; $this->retryFunction = $retryFunction; } /** * Executes the retry process. * * @param callable $function * @param array $arguments [optional] * @return mixed * @throws \Exception The last exception caught while retrying. */ public function execute(callable $function, array $arguments = []) { $delayFunction = $this->delayFunction; $retryAttempt = 0; $continue = true; do { try { $res = call_user_func_array($function, $arguments); $continue = false; return $res; } catch (\Exception $exception) { if ($this->retryFunction) { if (!call_user_func($this->retryFunction, $exception)) { throw $exception; } } if ($retryAttempt < $this->retries) { $delay = $delayFunction($exception); $delay += ['seconds' => 0, 'nanos' => 0]; time_nanosleep($delay['seconds'], $delay['nanos']); $retryAttempt++; } else { $continue = false; throw $exception; } } } while ($continue); } /** * @param callable $delayFunction * @return void */ public function setDelayFunction(callable $delayFunction) { $this->delayFunction = $delayFunction; } }