Passed
Branch feature/first-release (e5a99d)
by Andrea Marco
01:47
created

RetriesHttpRequests::backoff()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
cc 2
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Cerbero\LazyJsonPages\Concerns;
4
5
use Cerbero\LazyJsonPages\Exceptions\OutOfAttemptsException;
6
use Cerbero\LazyJsonPages\Outcome;
7
use Throwable;
8
9
/**
10
 * The trait to retry HTTP requests when they fail.
11
 *
12
 */
13
trait RetriesHttpRequests
14
{
15
    /**
16
     * Retry to return the result of HTTP requests
17
     *
18
     * @param callable $callback
19
     * @return mixed
20
     */
21 11
    protected function retry(callable $callback)
22
    {
23 11
        $attempt = 0;
24 11
        $outcome = new Outcome();
25 11
        $remainingAttempts = $this->config->attempts;
26
27
        do {
28 11
            $attempt++;
29 11
            $remainingAttempts--;
30
31
            try {
32 11
                return $callback($outcome);
33 1
            } catch (Throwable $e) {
34 1
                if ($remainingAttempts > 0) {
35 1
                    $this->backoff($attempt);
36
                } else {
37 1
                    throw new OutOfAttemptsException($e, $outcome);
38
                }
39
            }
40 1
        } while ($remainingAttempts > 0);
41
    }
42
43
    /**
44
     * Execute the backoff strategy
45
     *
46
     * @param int $attempt
47
     * @return void
48
     */
49 2
    protected function backoff(int $attempt): void
50
    {
51 2
        $backoff = $this->config->backoff ?: function (int $attempt) {
52 2
            return ($attempt - 1) ** 2 * 1000;
53 2
        };
54
55 2
        usleep($backoff($attempt) * 1000);
56 2
    }
57
58
    /**
59
     * Retry to yield the result of HTTP requests
60
     *
61
     * @param callable $callback
62
     * @return mixed
63
     */
64 2
    protected function retryYielding(callable $callback)
65
    {
66 2
        $attempt = 0;
67 2
        $outcome = new Outcome();
68 2
        $remainingAttempts = $this->config->attempts;
69
70
        do {
71 2
            $failed = false;
72 2
            $attempt++;
73 2
            $remainingAttempts--;
74
75
            try {
76 2
                yield from $callback($outcome);
77 1
            } catch (Throwable $e) {
78 1
                $failed = true;
79
80 1
                if ($remainingAttempts > 0) {
81 1
                    $this->backoff($attempt);
82
                } else {
83 1
                    throw new OutOfAttemptsException($e, $outcome);
84
                }
85
            }
86 2
        } while ($failed && $remainingAttempts > 0);
87 1
    }
88
}
89