FirstLevelRetryPipelineStep::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
namespace PSB\Core\ErrorHandling\FirstLevelRetry\Pipeline;
3
4
5
use PSB\Core\ErrorHandling\FirstLevelRetry\FirstLevelRetryHeaderTypeEnum;
6
use PSB\Core\ErrorHandling\FirstLevelRetry\FirstLevelRetryPolicy;
7
use PSB\Core\ErrorHandling\FirstLevelRetry\FirstLevelRetryStorage;
8
use PSB\Core\Exception\CriticalErrorException;
9
use PSB\Core\Exception\MessageDeserializationException;
10
use PSB\Core\Pipeline\Incoming\StageContext\TransportReceiveContext;
11
use PSB\Core\Pipeline\PipelineStepInterface;
12
13
class FirstLevelRetryPipelineStep implements PipelineStepInterface
14
{
15
    /**
16
     * @var FirstLevelRetryStorage
17
     */
18
    private $retryStorage;
19
20
    /**
21
     * @var FirstLevelRetryPolicy
22
     */
23
    private $retryPolicy;
24
25
    /**
26
     * @param FirstLevelRetryStorage $retryStorage
27
     * @param FirstLevelRetryPolicy  $retryPolicy
28
     */
29 7
    public function __construct(FirstLevelRetryStorage $retryStorage, FirstLevelRetryPolicy $retryPolicy)
30
    {
31 7
        $this->retryStorage = $retryStorage;
32 7
        $this->retryPolicy = $retryPolicy;
33 7
    }
34
35
    /**
36
     * @param TransportReceiveContext $context
37
     * @param callable                $next
38
     *
39
     * @throws \Throwable
40
     */
41 5
    public function invoke($context, callable $next)
42
    {
43
        try {
44 5
            $next();
45 4
        } catch (CriticalErrorException $e) {
46
            // no retry for critical errors
47 1
            throw $e;
48 3
        } catch (MessageDeserializationException $e) {
49
            // no retry for invalid messages
50 1
            throw $e;
51 2
        } catch (\Throwable $t) {
52 2
            $messageId = $context->getMessageId();
53
54 2
            $numberOfRetries = $this->retryStorage->getFailuresForMessage($messageId);
55
56 2
            if ($this->retryPolicy->shouldGiveUp($numberOfRetries)) {
57 1
                $this->retryStorage->clearFailuresForMessage($messageId);
58
59 1
                $message = $context->getMessage();
60 1
                $message->setHeader(FirstLevelRetryHeaderTypeEnum::RETRIES, $numberOfRetries);
61
62 1
                throw $t;
63
            }
64
65 1
            $this->retryStorage->incrementFailuresForMessage($context->getMessageId());
66 1
            $context->abortReceiveOperation();
67
        }
68 2
    }
69
70
    /**
71
     * @return string
72
     */
73 1
    public static function getStageContextClass()
74
    {
75 1
        return TransportReceiveContext::class;
76
    }
77
}
78