Skip to content

Commit 7a7db7d

Browse files
Convert envelope trait to abstract class (#231)
1 parent 7ac5da4 commit 7a7db7d

File tree

13 files changed

+110
-159
lines changed

13 files changed

+110
-159
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"psr/container": "^1.0 || ^2.0",
4141
"psr/log": "^2.0 || ^3.0",
4242
"symfony/console": "^5.4 || ^6.0 || ^7.0",
43+
"yiisoft/arrays": "^3.1",
4344
"yiisoft/definitions": "^3.3.1",
4445
"yiisoft/factory": "^1.3",
4546
"yiisoft/friendly-exception": "^1.0",

phpbench.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema":"./vendor/phpbench/phpbench/phpbench.schema.json",
33
"runner.bootstrap": "vendor/autoload.php",
44
"runner.path": "tests/Benchmark",
5-
"runner.revs": 1000,
5+
"runner.revs": 100000,
66
"runner.iterations": 5,
77
"runner.warmup": 5
88
}

src/Message/Envelope.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Queue\Message;
6+
7+
abstract class Envelope implements EnvelopeInterface
8+
{
9+
private ?array $metadata = null;
10+
11+
public function __construct(protected MessageInterface $message)
12+
{
13+
}
14+
15+
/** @psalm-suppress MoreSpecificReturnType */
16+
public static function fromData(string $handlerName, mixed $data, array $metadata = []): static
17+
{
18+
/** @psalm-suppress LessSpecificReturnStatement */
19+
return static::fromMessage(Message::fromData($handlerName, $data, $metadata));
20+
}
21+
22+
public function getMessage(): MessageInterface
23+
{
24+
return $this->message;
25+
}
26+
27+
public function getHandlerName(): string
28+
{
29+
return $this->message->getHandlerName();
30+
}
31+
32+
public function getData(): mixed
33+
{
34+
return $this->message->getData();
35+
}
36+
37+
public function getMetadata(): array
38+
{
39+
if ($this->metadata === null) {
40+
$messageMeta = $this->message->getMetadata();
41+
42+
$stack = $messageMeta[EnvelopeInterface::ENVELOPE_STACK_KEY] ?? [];
43+
if (!is_array($stack)) {
44+
$stack = [];
45+
}
46+
47+
$this->metadata = array_merge(
48+
$messageMeta,
49+
[
50+
EnvelopeInterface::ENVELOPE_STACK_KEY => array_merge(
51+
$stack,
52+
[static::class],
53+
),
54+
],
55+
$this->getEnvelopeMetadata(),
56+
);
57+
}
58+
59+
return $this->metadata;
60+
}
61+
62+
abstract protected function getEnvelopeMetadata(): array;
63+
}

src/Message/EnvelopeInterface.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ interface EnvelopeInterface extends MessageInterface
1212
/** @psalm-suppress MissingClassConstType */
1313
public const ENVELOPE_STACK_KEY = 'envelopes';
1414

15-
public static function fromMessage(MessageInterface $message): self;
15+
public static function fromMessage(MessageInterface $message): static;
1616

1717
public function getMessage(): MessageInterface;
18-
19-
public function withMessage(MessageInterface $message): self;
2018
}

src/Message/EnvelopeTrait.php

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/Message/IdEnvelope.php

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,42 @@
55
namespace Yiisoft\Queue\Message;
66

77
/**
8-
* ID envelope allows identifying a message.
8+
* ID envelope allows to identify a message.
99
*/
10-
final class IdEnvelope implements EnvelopeInterface
10+
final class IdEnvelope extends Envelope
1111
{
12-
use EnvelopeTrait;
13-
1412
public const MESSAGE_ID_KEY = 'yii-message-id';
1513

1614
public function __construct(
17-
MessageInterface $message,
18-
private readonly string|int|null $id = null,
15+
protected MessageInterface $message,
16+
private readonly string|int|null $id,
1917
) {
20-
$this->message = $message;
2118
}
2219

23-
public static function fromMessage(MessageInterface $message): self
20+
public static function fromMessage(MessageInterface $message): static
2421
{
25-
return new self($message, self::getIdFromMessage($message));
22+
/** @var mixed $rawId */
23+
$rawId = $message->getMetadata()[self::MESSAGE_ID_KEY] ?? null;
24+
25+
/** @var int|string|null $id */
26+
$id = match (true) {
27+
$rawId === null => null, // don't remove this branch: it's important for compute speed
28+
is_string($rawId) => $rawId,
29+
is_int($rawId) => $rawId,
30+
is_object($rawId) && method_exists($rawId, '__toString') => (string)$rawId,
31+
default => null,
32+
};
33+
34+
return new self($message, $id);
2635
}
2736

2837
public function getId(): string|int|null
2938
{
30-
return $this->id ?? self::getIdFromMessage($this->message);
39+
return $this->id;
3140
}
3241

33-
private function getEnvelopeMetadata(): array
42+
protected function getEnvelopeMetadata(): array
3443
{
3544
return [self::MESSAGE_ID_KEY => $this->getId()];
3645
}
37-
38-
private static function getIdFromMessage(MessageInterface $message): string|int|null
39-
{
40-
$id = $message->getMetadata()[self::MESSAGE_ID_KEY] ?? null;
41-
if ($id instanceof \Stringable) {
42-
$id = (string) $id;
43-
}
44-
45-
// We don't throw an error as this value could come from external sources,
46-
// and we should process the message either way
47-
if (!is_string($id) && !is_int($id)) {
48-
return null;
49-
}
50-
51-
return $id;
52-
}
5346
}

src/Message/Message.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
final class Message implements MessageInterface
88
{
99
/**
10+
* @param string $handlerName A name of a handler which should handle this message.
1011
* @param mixed $data Message data, encodable by a queue adapter
1112
* @param array $metadata Message metadata, encodable by a queue adapter
1213
*/
@@ -36,12 +37,4 @@ public function getMetadata(): array
3637
{
3738
return $this->metadata;
3839
}
39-
40-
public function withMetadata(array $metadata): self
41-
{
42-
$instance = clone $this;
43-
$instance->metadata = $metadata;
44-
45-
return $instance;
46-
}
4740
}

src/Message/MessageInterface.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,16 @@ public static function fromData(string $handlerName, mixed $data, array $metadat
1010

1111
/**
1212
* Returns handler name.
13-
*
14-
* @return string
1513
*/
1614
public function getHandlerName(): string;
1715

1816
/**
1917
* Returns payload data.
20-
*
21-
* @return mixed
2218
*/
2319
public function getData(): mixed;
2420

2521
/**
2622
* Returns message metadata: timings, attempts count, metrics, etc.
27-
*
28-
* @return array
2923
*/
3024
public function getMetadata(): array;
3125
}

src/Middleware/FailureHandling/FailureEnvelope.php

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,33 @@
44

55
namespace Yiisoft\Queue\Middleware\FailureHandling;
66

7-
use Yiisoft\Queue\Message\EnvelopeInterface;
8-
use Yiisoft\Queue\Message\EnvelopeTrait;
7+
use Yiisoft\Arrays\ArrayHelper;
8+
use Yiisoft\Queue\Message\Envelope;
99
use Yiisoft\Queue\Message\MessageInterface;
1010

11-
final class FailureEnvelope implements EnvelopeInterface
11+
final class FailureEnvelope extends Envelope
1212
{
13-
use EnvelopeTrait {
14-
getMetadata as getMetadataParent;
15-
}
16-
1713
public const FAILURE_META_KEY = 'failure-meta';
1814

1915
public function __construct(
20-
MessageInterface $message,
21-
private readonly array $meta = [],
16+
protected MessageInterface $message,
17+
private readonly array $metadata = [],
2218
) {
23-
$this->message = $message;
2419
}
2520

26-
public static function fromMessage(MessageInterface $message): self
21+
public static function fromMessage(MessageInterface $message): static
2722
{
28-
return new self($message, $message->getMetadata()[self::FAILURE_META_KEY] ?? []);
23+
/** @var array $metadata */
24+
$metadata = $message->getMetadata()[self::FAILURE_META_KEY] ?? [];
25+
26+
return new self($message, $metadata);
2927
}
3028

31-
public function getMetadata(): array
29+
protected function getEnvelopeMetadata(): array
3230
{
33-
$meta = $this->getMetadataParent();
34-
$meta[self::FAILURE_META_KEY] = array_merge($meta[self::FAILURE_META_KEY] ?? [], $this->meta);
31+
/** @var array $metadata */
32+
$metadata = $this->message->getMetadata()[self::FAILURE_META_KEY] ?? [];
3533

36-
return $meta;
34+
return [self::FAILURE_META_KEY => ArrayHelper::merge($metadata, $this->metadata)];
3735
}
3836
}

tests/App/DummyEnvelope.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@
44

55
namespace Yiisoft\Queue\Tests\App;
66

7-
use Yiisoft\Queue\Message\EnvelopeInterface;
8-
use Yiisoft\Queue\Message\EnvelopeTrait;
7+
use Yiisoft\Queue\Message\Envelope;
98
use Yiisoft\Queue\Message\MessageInterface;
109

11-
final class DummyEnvelope implements EnvelopeInterface
10+
final class DummyEnvelope extends Envelope
1211
{
13-
use EnvelopeTrait;
14-
15-
public static function fromMessage(MessageInterface $message): self
12+
public static function fromMessage(MessageInterface $message): static
1613
{
17-
$instance = new self();
18-
$instance->message = $message;
14+
return new self($message);
15+
}
1916

20-
return $instance;
17+
protected function getEnvelopeMetadata(): array
18+
{
19+
return [];
2120
}
2221
}

0 commit comments

Comments
 (0)