gousto/replay

Replay 允许您为您的函数计划重试和回退策略。

1.0.1 2017-07-31 14:33 UTC

This package is not auto-updated.

Last update: 2024-09-24 17:47:40 UTC


README

CircleCI GitHub tag Scrutinizer

重放出错的函数!

有些时候事情并不总是第一次尝试就成功。 Replay 允许您为您的函数规划 重试回退 策略。

安装

composer require gousto/replay

功能

  • 在异常范围内重试函数
  • 每次尝试增加延迟
  • 创建高级重试回退策略

用法

如果您想重放一个在抛出 异常 时抛出的函数,以下是一个示例

<?php

use Gousto\Replay\Replay;

try {

    $result = Replay::retry(3, function() {
       return Http::get('example.com'); 
    }, 50);
    
    Log::info("All good");
} catch(\Gousto\Replay\RetryLogicException $e) {
    \Log::error("After 3 times the function still error out!");
}

如果未发生任何 异常,此代码将立即返回 Http::get() 的结果。

在发生 异常 的情况下,它将再次尝试最多 3 次,每次尝试间隔 50ms

每次尝试增加延迟

假设我们想要一个重试策略,该策略希望在每次尝试时增加间隔 :第一次尝试 10ms,第二次尝试 20ms,第三次尝试 40ms

<?php

use Gousto\Replay\Replay;

$replay = Replay::times(3, function() {

    throw new LogicException();
  
}, 10);

$replay->onRetry(function(Exception $e, Replay $replay) {
   $replay->setDelay($replay->getDelay() * 2); 
});

// play the strategy!
$replay->play();

自定义异常

Replay 允许您仅针对特定的 异常 触发重试逻辑,将异常类名称数组作为第四个参数传递

<?php

use Gousto\Replay\Replay;

// Will throw LogicException and not retry
Replay::retry(3, function() {

    throw new LogicException();
  
}, 0, [RuntimeException::class]);

当函数被调用时,将抛出 LogicException。我们只在抛出 RuntimeException 时重试。

API

- retry($attempts = 1, Closure $user_function, $delay = 0, $exception_targets = [Exception::class])

如果没有发生异常,则返回闭包的结果。否则,将重试调用函数,直到达到指定的尝试次数。如果剩余尝试次数为 0,则抛出 Gousto\Replay\RetryLogicException::class

  • $attempts:int,函数可能重放的最大尝试次数
  • $user_function: Closure,如果出错则重放的函数
  • $delay: int,延迟以毫秒为单位
  • $exception_targets: array,将考虑为错误的异常列表
use Gousto\Replay\Replay;

Replay::retry(1, function() {

    throw new Exception();
  
}, 0, [Exception::class]);

- times($attempts = 1, Closure $user_function, $delay = 0, $exception_targets = [])

用于实例化 Replay 的辅助函数,便于链式调用

  • $attempts:int,函数可能重放的最大尝试次数
  • $user_function: Closure,如果出错则重放的函数
  • $delay: int,延迟以毫秒为单位
  • $exception_targets: array,将考虑为错误的异常列表
use Gousto\Replay\Replay;

$replay = Replay::times(1, function() {

    throw new Exception();
  
}, 0, [Exception::class]);

$replay->play();

play($silent = false)

告诉 replay 调用函数并在需要时使用重试逻辑。

  • $silent: bool,如果为 true,则不会抛出 RetryLogicException 但会返回它。
use Gousto\Replay\Replay;

$replay = Replay::times(2, function() {

    throw new Exception();
  
}, 0, [Exception::class]);

$result = $replay->play(true); // $result instanceof RetryLogicException

$replay->play(); // throw RetryLogicException

onRetry(Closure $handler)

为每次尝试触发一个函数,这对于记录或其他操作非常有用。

use Gousto\Replay\Replay;

$counter = 0;
$replay = Replay::times(3, function() use (&$counter) {
    $counter++;
    if ($counter === 3) {
        return $counter;
    }
    throw new Exception("Error"); 
});

// WILL LOG:
// Attempt 1: Failed
// Attempt 2: Failed
$replay->onRetry(function(Exception $exception, Replay $replay) {
   Log::error("Attempt {$replay->attempts()}: Failed"); 
});

try {
    $replay->play();
} catch(\Gousto\Replay\RetryLogicException $e) {
    
}

next()

next 函数允许您手动控制重试周期

use Gousto\Replay\Replay;

$replay = Replay::times(3, function() {

    throw new Exception();
  
}, 0, [Exception::class]);

$replay->next(); // 1 attempt
$replay->next(); // 2 attempts
$replay->next(); // Throw RetryLogicException

attempts()

返回重试尝试的次数

use Gousto\Replay\Replay;

$replay = Replay::times(3, function() {

    throw new Exception();
  
}, 0, [Exception::class]);

$replay->next();
$replay->attempts(); // 1

$replay->next();
$replay->attempts(); // 2

isErrored()

返回函数调用的状态

$replay = Replay::times(4, function() {

    return 10;
  
}, 0, [Exception::class]);

$result = $replay->play(); // 10

$replay->isErrored(); // False

致谢

www.gousto.co.uk