Passed
Push — master ( a32f43...4dbc55 )
by Herberto
05:27
created

AsynchronousMessage::getDestination()   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 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Werkspot\MessageBus\Message;
4
5
use DateInterval;
6
use DateTime;
7
use DateTimeImmutable;
8
use Ramsey\Uuid\Uuid;
9
use Throwable;
10
use Werkspot\MessageBus\MessageQueue\AsynchronousMessageInterface;
11
use Werkspot\MessageBus\MessageQueue\Priority;
12
13
final class AsynchronousMessage implements AsynchronousMessageInterface, MessageInterface
14
{
15
    /**
16
     * @var string
17
     */
18
    private $id;
19
20
    /**
21
     * @var string
22
     */
23
    private $destination;
24
25
    /**
26
     * @var mixed
27
     */
28
    private $payload;
29
30
    /**
31
     * @var Priority
32
     */
33
    private $priority;
34
35
    /**
36
     * @var DateTimeImmutable
37
     */
38
    private $deliverAt;
39
40
    /**
41
     * @var DateTimeImmutable
42
     */
43
    private $createdAt;
44
45
    /**
46
     * @var DateTimeImmutable|null
47
     */
48
    private $updatedAt;
49
50
    /**
51
     * @var int
52
     */
53
    private $tries = 0;
54
55
    /**
56
     * @var string|null
57
     */
58
    private $errors;
59
60
    /**
61
     * @var array
62
     */
63
    private $metadata;
64
65 7
    public function __construct(
66
        $payload,
67
        string $destination,
68
        array $metadata = [],
69
        DateTimeImmutable $deliverAt = null,
70
        Priority $priority = null
71
    ) {
72 7
        $this->id = Uuid::uuid4()->toString();
73 7
        $this->payload = $payload;
74 7
        $this->destination = $destination;
75 7
        $this->metadata = $metadata;
76 7
        $this->deliverAt = $deliverAt ?? $this->defineDeliveryDate();
77 7
        $this->priority = $priority ?? new Priority(Priority::NORMAL);
78 7
        $this->createdAt = new DateTimeImmutable();
79 7
    }
80
81 1
    public function getId(): string
82
    {
83 1
        return $this->id;
84
    }
85
86 4
    public function getDestination(): string
87
    {
88 4
        return $this->destination;
89
    }
90
91
    /**
92
     * @return mixed
93
     */
94 5
    public function getPayload()
95
    {
96 5
        return $this->payload;
97
    }
98
99 4
    public function getPriority(): Priority
100
    {
101 4
        return $this->priority;
102
    }
103
104 3
    public function getDeliverAt(): DateTimeImmutable
105
    {
106 3
        return $this->deliverAt;
107
    }
108
109 1
    public function getCreatedAt(): DateTimeImmutable
110
    {
111 1
        return $this->createdAt;
112
    }
113
114 1
    public function getUpdatedAt(): ?DateTimeImmutable
115
    {
116 1
        return $this->updatedAt;
117
    }
118
119 3
    public function getTries(): int
120
    {
121 3
        return $this->tries;
122
    }
123
124 1
    public function getErrors(): ?string
125
    {
126 1
        return $this->errors;
127
    }
128
129 1
    public function fail(Throwable $error): void
130
    {
131 1
        $now = new DateTimeImmutable();
132
133 1
        $errorMessage = sprintf(
134 1
            "[%s] '%s': '%s'\n%s",
135 1
            $now->format(DateTime::ATOM),
136 1
            get_class($error),
137 1
            $error->getMessage(),
138 1
            $error->getTraceAsString()
139
        );
140
141 1
        $this->errors .= $errorMessage . "\n\n";
142
143 1
        $this->tries++;
144 1
        $this->updateDeliveryDate();
145 1
    }
146
147 1
    private function updateDeliveryDate(): void
148
    {
149 1
        $this->deliverAt = $this->defineDeliveryDate();
150 1
    }
151
152 4
    private function defineDeliveryDate(): DateTimeImmutable
153
    {
154 4
        $interval = $this->getDateTimeIntervalForTry($this->tries + 1);
155
156 4
        return (new DateTimeImmutable())->add($interval);
157
    }
158
159
    /**
160
     * By default we try the command in:
161
     *  - try 1: 0 minutes
162
     *  - try 2: 1 minutes
163
     *  - try 3: 4 minutes
164
     *  - try 4: 9 minutes
165
     *
166
     * @param int $try The try of the command, try 1 is the first time the message is delivered
167
     */
168 4
    private function getDateTimeIntervalForTry(int $try): DateInterval
169
    {
170 4
        $waitingTimeInMinutes = ($try - 1) * ($try - 1);
171
172 4
        return new DateInterval(sprintf('PT%dM', $waitingTimeInMinutes));
173
    }
174
175 2
    public function getMetadata(): array
176
    {
177 2
        return $this->metadata;
178
    }
179
}
180