Completed
Push — master ( 4248bc...046bb8 )
by Peter
7s
created

RetryProcessor::getMaxAttempts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace TreeHouse\Queue\Processor\Retry;
4
5
use Psr\Log\LoggerInterface;
6
use TreeHouse\Queue\Amqp\EnvelopeInterface;
7
use TreeHouse\Queue\Exception\ProcessExhaustedException;
8
use TreeHouse\Queue\Processor\ProcessorInterface;
9
10
/**
11
 * Processor that performs a number of attempts when a message could not be processed.
12
 */
13
class RetryProcessor implements ProcessorInterface
14
{
15
    const PROPERTY_KEY = 'attempt';
16
17
    /**
18
     * @var ProcessorInterface
19
     */
20
    protected $processor;
21
22
    /**
23
     * @var RetryStrategyInterface
24
     */
25
    protected $strategy;
26
27
    /**
28
     * @var LoggerInterface
29
     */
30
    protected $logger;
31
32
    /**
33
     * @var int
34
     */
35
    protected $maxAttempts = 2;
36
37
    /**
38
     * @param ProcessorInterface     $processor
39
     * @param RetryStrategyInterface $strategy
40
     * @param LoggerInterface        $logger
41
     */
42 5
    public function __construct(ProcessorInterface $processor, RetryStrategyInterface $strategy, LoggerInterface $logger = null)
43
    {
44 5
        $this->processor = $processor;
45 5
        $this->strategy = $strategy;
46 5
        $this->logger = $logger;
47 5
    }
48
49
    /**
50
     * @param ProcessorInterface $processor
51
     */
52 1
    public function setProcessor($processor)
53
    {
54 1
        $this->processor = $processor;
55 1
    }
56
57
    /**
58
     * @return ProcessorInterface
59
     */
60 1
    public function getProcessor()
61
    {
62 1
        return $this->processor;
63
    }
64
65
    /**
66
     * @param int $maxAttempts
67
     */
68 2
    public function setMaxAttempts($maxAttempts)
69
    {
70 2
        $this->maxAttempts = $maxAttempts;
71 2
    }
72
73
    /**
74
     * @return int
75
     */
76 1
    public function getMaxAttempts()
77
    {
78 1
        return $this->maxAttempts;
79
    }
80
81
    /**
82
     * @inheritdoc
83
     */
84 3
    public function process(EnvelopeInterface $envelope)
85
    {
86
        try {
87 3
            $result = $this->processor->process($envelope);
88 2
        } catch (\Exception $exception) {
89 2
            if ($this->logger) {
90
                $this->logger->error($exception->getMessage(), ['message' => $envelope->getDeliveryTag()]);
91
            }
92
93 2
            $result = $this->retryMessage($envelope, $exception);
94
        }
95
96 2
        return $result;
97
    }
98
99
    /**
100
     * @param EnvelopeInterface $envelope
101
     * @param \Exception        $exception
102
     *
103
     * @throws ProcessExhaustedException
104
     *
105
     * @return bool
106
     */
107 2
    protected function retryMessage(EnvelopeInterface $envelope, \Exception $exception = null)
108
    {
109 2
        $attempt = $this->getAttemptValue($envelope);
110 2
        if ($attempt >= $this->maxAttempts) {
111 1
            throw new ProcessExhaustedException(sprintf('Exhausted after failing %d attempt(s)', $attempt));
112
        }
113
114 1
        if ($this->logger) {
115
            $this->logger->debug(sprintf('Requeueing message (%d attempts left)', $this->maxAttempts - $attempt));
116
        }
117
118 1
        return $this->strategy->retry($envelope, ++$attempt, $exception);
119
    }
120
121
    /**
122
     * @param EnvelopeInterface $envelope
123
     *
124
     * @throws \LogicException
125
     *
126
     * @return int
127
     */
128 2
    protected function getAttemptValue(EnvelopeInterface $envelope)
129
    {
130 2
        if (false === $attempt = $envelope->getHeader(self::PROPERTY_KEY)) {
131
            return 1;
132
        }
133
134 2
        $attempt = (integer) $attempt;
135
136 2
        if ($attempt < 1) {
137
            throw new \LogicException(
138
                sprintf('Attempt can only be a positive number, got "%s"', json_encode($attempt))
139
            );
140
        }
141
142 2
        return $attempt;
143
    }
144
}
145