Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8700123
Convert envelope trait to abstract class
viktorprogger Dec 15, 2024
3ecc37e
Require yiisoft/arrays package
viktorprogger Dec 15, 2024
bff438d
Merge branch 'master' into convert-envelope-trait-to-abstract-class
viktorprogger Feb 14, 2025
e4e4723
Merge remote-tracking branch 'origin/master' into convert-envelope-tr…
viktorprogger Feb 14, 2025
95b6ea4
Bugfixes
viktorprogger May 4, 2025
666d650
Apply fixes from StyleCI
StyleCIBot May 4, 2025
c6b758d
Rename FailureEnvelope::$failureMeta
viktorprogger May 4, 2025
7516793
Add more typing
viktorprogger May 4, 2025
198ea47
Merge remote-tracking branch 'origin/master' into convert-envelope-tr…
viktorprogger May 8, 2025
d0deac6
Fix envelope static constructors return types
viktorprogger May 8, 2025
fefb5cb
Add tests for the new code
viktorprogger May 8, 2025
1cdcfe1
Apply fixes from StyleCI
StyleCIBot May 8, 2025
3ec891f
Re-run checks
viktorprogger May 8, 2025
b63f5e7
Fix fromMessage() return types in implementations
viktorprogger May 8, 2025
f8c47ba
Apply fixes from StyleCI
StyleCIBot May 8, 2025
4370fa0
Ignore psalm false-positives
viktorprogger May 8, 2025
f3f388b
Memorise metadata in envelopes
viktorprogger May 9, 2025
cab6ab1
Get message metadata just once
viktorprogger Jul 13, 2025
d676a3c
Address performance issues
viktorprogger Jul 13, 2025
2340afc
Merge branch 'master' into convert-envelope-trait-to-abstract-class
viktorprogger Jul 14, 2025
5d9cd41
Merge branch 'master' into convert-envelope-trait-to-abstract-class
viktorprogger Jul 14, 2025
e7acc32
Fix IdEnvelope after master merge
viktorprogger Jul 14, 2025
0c1292d
Get back 100 000 bench revisions after master merge
viktorprogger Jul 14, 2025
076e8dd
Apply fixes from StyleCI
StyleCIBot Jul 14, 2025
209ba7b
Merge branch 'refs/heads/master' into convert-envelope-trait-to-abstr…
viktorprogger Jul 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"psr/container": "^1.0|^2.0",
"psr/log": "^2.0|^3.0",
"symfony/console": "^5.4|^6.0|^7.0",
"yiisoft/arrays": "^3.1",
"yiisoft/definitions": "^3.3.1",
"yiisoft/factory": "^1.3",
"yiisoft/friendly-exception": "^1.0",
Expand Down
26 changes: 6 additions & 20 deletions src/Message/EnvelopeTrait.php → src/Message/Envelope.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@

namespace Yiisoft\Queue\Message;

trait EnvelopeTrait
abstract class Envelope implements EnvelopeInterface
{
private MessageInterface $message;

/**
* A mirror of {@see MessageInterface::fromData()}
*/
abstract public static function fromMessage(MessageInterface $message): self;
public function __construct(protected MessageInterface $message)
{
}

public static function fromData(string $handlerName, mixed $data, array $metadata = []): MessageInterface
{
Expand All @@ -23,14 +20,6 @@ public function getMessage(): MessageInterface
return $this->message;
}

public function withMessage(MessageInterface $message): self
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Copy Markdown
Contributor Author

@viktorprogger viktorprogger May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any real-world use cases. Do you?

Copy link
Copy Markdown
Contributor Author

@viktorprogger viktorprogger Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another question.
Why is this better than FooEnvelope::fromMessage($message) or new FooEnvelope()?

{
$instance = clone $this;
$instance->message = $message;

return $instance;
}

public function getHandlerName(): string
{
return $this->message->getHandlerName();
Expand All @@ -48,15 +37,12 @@ public function getMetadata(): array
[
EnvelopeInterface::ENVELOPE_STACK_KEY => array_merge(
$this->message->getMetadata()[EnvelopeInterface::ENVELOPE_STACK_KEY] ?? [],
[self::class],
[static::class],
),
],
$this->getEnvelopeMetadata(),
);
}

public function getEnvelopeMetadata(): array
{
return [];
}
abstract protected function getEnvelopeMetadata(): array;
Comment thread
viktorprogger marked this conversation as resolved.
}
2 changes: 0 additions & 2 deletions src/Message/EnvelopeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,4 @@ interface EnvelopeInterface extends MessageInterface
public static function fromMessage(MessageInterface $message): self;

public function getMessage(): MessageInterface;

public function withMessage(MessageInterface $message): self;
}
16 changes: 5 additions & 11 deletions src/Message/IdEnvelope.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,28 @@
/**
* ID envelope allows to identify a message.
*/
final class IdEnvelope implements EnvelopeInterface
final class IdEnvelope extends Envelope
{
use EnvelopeTrait;

public const MESSAGE_ID_KEY = 'yii-message-id';

public function __construct(
private MessageInterface $message,
private string|int|null $id = null,
MessageInterface $message,
private readonly string|int|null $id,
) {
parent::__construct($message);
}

public static function fromMessage(MessageInterface $message): self
{
return new self($message, $message->getMetadata()[self::MESSAGE_ID_KEY] ?? null);
}

public function setId(string|int|null $id): void
{
$this->id = $id;
}

public function getId(): string|int|null
{
return $this->id ?? $this->message->getMetadata()[self::MESSAGE_ID_KEY] ?? null;
}

private function getEnvelopeMetadata(): array
protected function getEnvelopeMetadata(): array
{
return [self::MESSAGE_ID_KEY => $this->getId()];
}
Expand Down
10 changes: 1 addition & 9 deletions src/Message/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
final class Message implements MessageInterface
{
/**
* @param string $handlerName A name of a handler which should handle this message.
* @param mixed $data Message data, encodable by a queue adapter
* @param array $metadata Message metadata, encodable by a queue adapter
* @param string|null $id Message id
*/
public function __construct(
private string $handlerName,
Expand Down Expand Up @@ -37,12 +37,4 @@ public function getMetadata(): array
{
return $this->metadata;
}

public function withMetadata(array $metadata): self
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Copy Markdown
Contributor Author

@viktorprogger viktorprogger May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any real-world use cases. Do you?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message handlers may add metadata into the message

Copy link
Copy Markdown
Contributor Author

@viktorprogger viktorprogger Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They should wrap it into an envelope then.

{
$instance = clone $this;
$instance->metadata = $metadata;

return $instance;
}
}
6 changes: 0 additions & 6 deletions src/Message/MessageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,16 @@ public static function fromData(string $handlerName, mixed $data, array $metadat

/**
* Returns handler name.
*
* @return string
*/
public function getHandlerName(): string;

/**
* Returns payload data.
*
* @return mixed
*/
public function getData(): mixed;

/**
* Returns message metadata: timings, attempts count, metrics, etc.
*
* @return array
*/
public function getMetadata(): array;
}
20 changes: 8 additions & 12 deletions src/Middleware/FailureHandling/FailureEnvelope.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,28 @@

namespace Yiisoft\Queue\Middleware\FailureHandling;

use Yiisoft\Queue\Message\EnvelopeInterface;
use Yiisoft\Queue\Message\EnvelopeTrait;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Queue\Message\Envelope;
use Yiisoft\Queue\Message\MessageInterface;

final class FailureEnvelope implements EnvelopeInterface
final class FailureEnvelope extends Envelope
{
use EnvelopeTrait;

public const FAILURE_META_KEY = 'failure-meta';

public function __construct(
private MessageInterface $message,
private array $meta = [],
MessageInterface $message,
private readonly array $failureMeta = [],
Comment thread
viktorprogger marked this conversation as resolved.
Outdated
) {
parent::__construct($message);
}

public static function fromMessage(MessageInterface $message): self
{
return new self($message, $message->getMetadata()[self::FAILURE_META_KEY] ?? []);
}

public function getMetadata(): array
protected function getEnvelopeMetadata(): array
{
$meta = $this->message->getMetadata();
$meta[self::FAILURE_META_KEY] = array_merge($meta[self::FAILURE_META_KEY] ?? [], $this->meta);

return $meta;
return [self::FAILURE_META_KEY => ArrayHelper::merge($this->message->getMetadata()[self::FAILURE_META_KEY] ?? [], $this->failureMeta)];
Comment thread
viktorprogger marked this conversation as resolved.
Outdated
}
}
2 changes: 1 addition & 1 deletion tests/Unit/Message/JsonMessageSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public function testRestoreOriginalMessageClass(): void

public function testRestoreOriginalMessageClassWithEnvelope(): void
{
$message = new IdEnvelope(new TestMessage());
$message = new IdEnvelope(new TestMessage(), 1);
$serializer = $this->createSerializer();
$serializer->unserialize($serializer->serialize($message));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,6 @@ public function testQueueSendingStrategies(
$this->expectExceptionMessage('testException');
}

$metaInitial = [FailureEnvelope::FAILURE_META_KEY => $metaInitial];
$metaResult = [FailureEnvelope::FAILURE_META_KEY => $metaResult];

$handler = $this->getHandler($metaResult, $suites);
$queue = $this->getPreparedQueue($metaResult, $suites);

Expand All @@ -162,7 +159,7 @@ public function testQueueSendingStrategies(
new Message(
'test',
null,
$metaInitial
[FailureEnvelope::FAILURE_META_KEY => $metaInitial]
),
new Exception('testException'),
$queue
Expand Down Expand Up @@ -194,7 +191,7 @@ private function getHandler(array $metaResult, bool $suites): MessageFailureHand
$pipelineAssertion = static function (FailureHandlingRequest $request) use (
$metaResult
): FailureHandlingRequest {
Assert::assertEquals($metaResult, $request->getMessage()->getMetadata());
Assert::assertEquals($metaResult, $request->getMessage()->getMetadata()[FailureEnvelope::FAILURE_META_KEY] ?? []);

throw $request->getException();
};
Expand All @@ -209,7 +206,7 @@ private function getHandler(array $metaResult, bool $suites): MessageFailureHand
private function getPreparedQueue(array $metaResult, bool $suites): QueueInterface
{
$queueAssertion = static function (MessageInterface $message) use ($metaResult): MessageInterface {
Assert::assertEquals($metaResult, $message->getMetadata());
Assert::assertEquals($metaResult, $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY] ?? []);

return $message;
};
Expand Down