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

SendAgainMiddleware::suites()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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