95 lines
2.5 KiB
PHP
95 lines
2.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
|
|
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
|
|
*
|
|
* Licensed under The MIT License
|
|
* For full copyright and license information, please see the LICENSE.txt
|
|
* Redistributions of files must retain the above copyright notice.
|
|
*
|
|
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
|
|
* @link https://cakephp.org CakePHP(tm) Project
|
|
* @since 3.6.0
|
|
* @license https://opensource.org/licenses/mit-license.php MIT License
|
|
*/
|
|
namespace Cake\Core\Retry;
|
|
|
|
use Exception;
|
|
|
|
/**
|
|
* Allows any action to be retried in case of an exception.
|
|
*
|
|
* This class can be parametrized with a strategy, which will be followed
|
|
* to determine whether the action should be retried.
|
|
*/
|
|
class CommandRetry
|
|
{
|
|
/**
|
|
* The strategy to follow should the executed action fail.
|
|
*
|
|
* @var \Cake\Core\Retry\RetryStrategyInterface
|
|
*/
|
|
protected $strategy;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $maxRetries;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $numRetries;
|
|
|
|
/**
|
|
* Creates the CommandRetry object with the given strategy and retry count
|
|
*
|
|
* @param \Cake\Core\Retry\RetryStrategyInterface $strategy The strategy to follow should the action fail
|
|
* @param int $maxRetries The maximum number of retry attempts allowed
|
|
*/
|
|
public function __construct(RetryStrategyInterface $strategy, int $maxRetries = 1)
|
|
{
|
|
$this->strategy = $strategy;
|
|
$this->maxRetries = $maxRetries;
|
|
}
|
|
|
|
/**
|
|
* The number of retries to perform in case of failure
|
|
*
|
|
* @param callable $action The callable action to execute with a retry strategy
|
|
* @return mixed The return value of the passed action callable
|
|
* @throws \Exception
|
|
*/
|
|
public function run(callable $action)
|
|
{
|
|
$this->numRetries = 0;
|
|
while (true) {
|
|
try {
|
|
return $action();
|
|
} catch (Exception $e) {
|
|
if (
|
|
$this->numRetries < $this->maxRetries &&
|
|
$this->strategy->shouldRetry($e, $this->numRetries)
|
|
) {
|
|
$this->numRetries++;
|
|
continue;
|
|
}
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the last number of retry attemps.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getRetries(): int
|
|
{
|
|
return $this->numRetries;
|
|
}
|
|
}
|