Passed
Push — master ( 22a045...d231e8 )
by Viktor
13:31
created

SendAgainMiddleware   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Test Coverage

Coverage 95.45%

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 59
ccs 21
cts 22
cp 0.9545
rs 10
c 0
b 0
f 0
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A suites() 0 3 1
A __construct() 0 7 2
A createMeta() 0 3 1
A getAttempts() 0 8 2
A processFailure() 0 14 2
A getMetaKey() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Queue\Middleware\FailureHandling\Implementation;
6
7
use InvalidArgumentException;
8
use Yiisoft\Queue\Message\MessageInterface;
9
use Yiisoft\Queue\Middleware\FailureHandling\FailureEnvelope;
10
use Yiisoft\Queue\Middleware\FailureHandling\FailureHandlingRequest;
11
use Yiisoft\Queue\Middleware\FailureHandling\MessageFailureHandlerInterface;
12
use Yiisoft\Queue\Middleware\FailureHandling\MiddlewareFailureInterface;
13
use Yiisoft\Queue\QueueInterface;
14
15
/**
16
 * Failure strategy which resends the given message to a queue.
17
 */
18
final class SendAgainMiddleware implements MiddlewareFailureInterface
19
{
20
    public const META_KEY_RESEND = 'failure-strategy-resend-attempts';
21
22
    /**
23
     * @param string $id A unique id to differentiate two and more instances of this class
24
     * @param int $maxAttempts Maximum attempts count for this strategy with the given $id before it will give up
25
     * @param QueueInterface|null $targetQueue Messages will be sent to this queue if set.
26
     *        They will be resent to an original queue otherwise.
27
     */
28 5
    public function __construct(
29
        private string $id,
30
        private int $maxAttempts,
31
        private ?QueueInterface $targetQueue = null,
32
    ) {
33 5
        if ($maxAttempts < 1) {
34
            throw new InvalidArgumentException("maxAttempts parameter must be a positive integer, $this->maxAttempts given.");
35
        }
36
    }
37
38 5
    public function processFailure(
39
        FailureHandlingRequest $request,
40
        MessageFailureHandlerInterface $handler
41
    ): FailureHandlingRequest {
42 5
        $message = $request->getMessage();
43 5
        if ($this->suites($message)) {
44 3
            $envelope = new FailureEnvelope($message, $this->createMeta($message));
45 3
            $envelope = ($this->targetQueue ?? $request->getQueue())->push($envelope);
46
47 3
            return $request->withMessage($envelope)
48 3
                ->withQueue($this->targetQueue ?? $request->getQueue());
49
        }
50
51 3
        return $handler->handleFailure($request);
52
    }
53
54 5
    private function suites(MessageInterface $message): bool
55
    {
56 5
        return $this->getAttempts($message) < $this->maxAttempts;
57
    }
58
59 3
    private function createMeta(MessageInterface $message): array
60
    {
61 3
        return [$this->getMetaKey() => $this->getAttempts($message) + 1];
62
    }
63
64 5
    private function getAttempts(MessageInterface $message): int
65
    {
66 5
        $result = $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY][$this->getMetaKey()] ?? 0;
67 5
        if ($result < 0) {
68 2
            $result = 0;
69
        }
70
71 5
        return (int) $result;
72
    }
73
74 5
    private function getMetaKey(): string
75
    {
76 5
        return self::META_KEY_RESEND . "-$this->id";
77
    }
78
}
79