Skip to content

Commit 46a8007

Browse files
committed
[Messenger] Allow InMemoryTransport to serialize message
1 parent 2a453c2 commit 46a8007

File tree

5 files changed

+186
-9
lines changed

5 files changed

+186
-9
lines changed

src/Symfony/Component/Messenger/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.3.0
5+
-----
6+
7+
* `InMemoryTransport` can perform message serialization through dsn `in-memory://?serialize=true`.
8+
49
5.2.0
510
-----
611

src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportFactoryTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,35 @@ public function testCreateTransport()
4949
$this->assertInstanceOf(InMemoryTransport::class, $this->factory->createTransport('in-memory://', [], $serializer));
5050
}
5151

52+
public function testCreateTransportWithoutSerializer()
53+
{
54+
/** @var SerializerInterface $serializer */
55+
$serializer = $this->createMock(SerializerInterface::class);
56+
$serializer
57+
->expects($this->never())
58+
->method('encode')
59+
;
60+
$transport = $this->factory->createTransport('in-memory://?serialize=false', [], $serializer);
61+
$message = Envelope::wrap(new DummyMessage('Hello.'));
62+
$transport->send($message);
63+
64+
$this->assertSame([$message], $transport->get());
65+
}
66+
67+
public function testCreateTransportWithSerializer()
68+
{
69+
/** @var SerializerInterface $serializer */
70+
$serializer = $this->createMock(SerializerInterface::class);
71+
$message = Envelope::wrap(new DummyMessage('Hello.'));
72+
$serializer
73+
->expects($this->once())
74+
->method('encode')
75+
->with($this->equalTo($message))
76+
;
77+
$transport = $this->factory->createTransport('in-memory://?serialize=true', [], $serializer);
78+
$transport->send($message);
79+
}
80+
5281
public function testResetCreatedTransports()
5382
{
5483
$transport = $this->factory->createTransport('in-memory://', [], $this->createMock(SerializerInterface::class));
@@ -63,6 +92,8 @@ public function provideDSN(): array
6392
{
6493
return [
6594
'Supported' => ['in-memory://foo'],
95+
'Serialize enabled' => ['in-memory://?serialize=true'],
96+
'Serialize disabled' => ['in-memory://?serialize=false'],
6697
'Unsupported' => ['amqp://bar', false],
6798
];
6899
}

src/Symfony/Component/Messenger/Tests/Transport/InMemoryTransportTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Messenger\Envelope;
1616
use Symfony\Component\Messenger\Tests\Fixtures\AnEnvelopeStamp;
17+
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
1718
use Symfony\Component\Messenger\Transport\InMemoryTransport;
19+
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
1820

1921
/**
2022
* @author Gary PEGEOT <garypegeot@gmail.com>
@@ -26,9 +28,21 @@ class InMemoryTransportTest extends TestCase
2628
*/
2729
private $transport;
2830

31+
/**
32+
* @var InMemoryTransport
33+
*/
34+
private $serializeTransport;
35+
36+
/**
37+
* @var SerializerInterface
38+
*/
39+
private $serializer;
40+
2941
protected function setUp(): void
3042
{
43+
$this->serializer = $this->createMock(SerializerInterface::class);
3144
$this->transport = new InMemoryTransport();
45+
$this->serializeTransport = new InMemoryTransport($this->serializer);
3246
}
3347

3448
public function testSend()
@@ -38,6 +52,24 @@ public function testSend()
3852
$this->assertSame([$envelope], $this->transport->getSent());
3953
}
4054

55+
public function testSendWithSerialization()
56+
{
57+
$envelope = new Envelope(new \stdClass());
58+
$envelopeDecoded = Envelope::wrap(new DummyMessage('Hello.'));
59+
$this->serializer
60+
->method('encode')
61+
->with($this->equalTo($envelope))
62+
->willReturn(['foo' => 'ba'])
63+
;
64+
$this->serializer
65+
->method('decode')
66+
->with(['foo' => 'ba'])
67+
->willReturn($envelopeDecoded)
68+
;
69+
$this->serializeTransport->send($envelope);
70+
$this->assertSame([$envelopeDecoded], $this->serializeTransport->getSent());
71+
}
72+
4173
public function testQueue()
4274
{
4375
$envelope1 = new Envelope(new \stdClass());
@@ -51,6 +83,24 @@ public function testQueue()
5183
$this->assertSame([], $this->transport->get());
5284
}
5385

86+
public function testQueueWithSerialization()
87+
{
88+
$envelope = new Envelope(new \stdClass());
89+
$envelopeDecoded = Envelope::wrap(new DummyMessage('Hello.'));
90+
$this->serializer
91+
->method('encode')
92+
->with($this->equalTo($envelope))
93+
->willReturn(['foo' => 'ba'])
94+
;
95+
$this->serializer
96+
->method('decode')
97+
->with(['foo' => 'ba'])
98+
->willReturn($envelopeDecoded)
99+
;
100+
$this->serializeTransport->send($envelope);
101+
$this->assertSame([$envelopeDecoded], $this->serializeTransport->get());
102+
}
103+
54104
public function testAcknowledgeSameMessageWithDifferentStamps()
55105
{
56106
$envelope1 = new Envelope(new \stdClass(), [new AnEnvelopeStamp()]);
@@ -71,13 +121,49 @@ public function testAck()
71121
$this->assertSame([$envelope], $this->transport->getAcknowledged());
72122
}
73123

124+
public function testAckWithSerialization()
125+
{
126+
$envelope = new Envelope(new \stdClass());
127+
$envelopeDecoded = Envelope::wrap(new DummyMessage('Hello.'));
128+
$this->serializer
129+
->method('encode')
130+
->with($this->equalTo($envelope))
131+
->willReturn(['foo' => 'ba'])
132+
;
133+
$this->serializer
134+
->method('decode')
135+
->with(['foo' => 'ba'])
136+
->willReturn($envelopeDecoded)
137+
;
138+
$this->serializeTransport->ack($envelope);
139+
$this->assertSame([$envelopeDecoded], $this->serializeTransport->getAcknowledged());
140+
}
141+
74142
public function testReject()
75143
{
76144
$envelope = new Envelope(new \stdClass());
77145
$this->transport->reject($envelope);
78146
$this->assertSame([$envelope], $this->transport->getRejected());
79147
}
80148

149+
public function testRejectWithSerialization()
150+
{
151+
$envelope = new Envelope(new \stdClass());
152+
$envelopeDecoded = Envelope::wrap(new DummyMessage('Hello.'));
153+
$this->serializer
154+
->method('encode')
155+
->with($this->equalTo($envelope))
156+
->willReturn(['foo' => 'ba'])
157+
;
158+
$this->serializer
159+
->method('decode')
160+
->with(['foo' => 'ba'])
161+
->willReturn($envelopeDecoded)
162+
;
163+
$this->serializeTransport->reject($envelope);
164+
$this->assertSame([$envelopeDecoded], $this->serializeTransport->getRejected());
165+
}
166+
81167
public function testReset()
82168
{
83169
$envelope = new Envelope(new \stdClass());

src/Symfony/Component/Messenger/Transport/InMemoryTransport.php

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Messenger\Transport;
1313

1414
use Symfony\Component\Messenger\Envelope;
15+
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
1516
use Symfony\Contracts\Service\ResetInterface;
1617

1718
/**
@@ -41,20 +42,30 @@ class InMemoryTransport implements TransportInterface, ResetInterface
4142
*/
4243
private $queue = [];
4344

45+
/**
46+
* @var SerializerInterface|null
47+
*/
48+
private $serializer;
49+
50+
public function __construct(SerializerInterface $serializer = null)
51+
{
52+
$this->serializer = $serializer;
53+
}
54+
4455
/**
4556
* {@inheritdoc}
4657
*/
4758
public function get(): iterable
4859
{
49-
return array_values($this->queue);
60+
return array_values($this->decode($this->queue));
5061
}
5162

5263
/**
5364
* {@inheritdoc}
5465
*/
5566
public function ack(Envelope $envelope): void
5667
{
57-
$this->acknowledged[] = $envelope;
68+
$this->acknowledged[] = $this->encode($envelope);
5869
$id = spl_object_hash($envelope->getMessage());
5970
unset($this->queue[$id]);
6071
}
@@ -64,7 +75,7 @@ public function ack(Envelope $envelope): void
6475
*/
6576
public function reject(Envelope $envelope): void
6677
{
67-
$this->rejected[] = $envelope;
78+
$this->rejected[] = $this->encode($envelope);
6879
$id = spl_object_hash($envelope->getMessage());
6980
unset($this->queue[$id]);
7081
}
@@ -74,9 +85,10 @@ public function reject(Envelope $envelope): void
7485
*/
7586
public function send(Envelope $envelope): Envelope
7687
{
77-
$this->sent[] = $envelope;
88+
$encodedEnvelope = $this->encode($envelope);
89+
$this->sent[] = $encodedEnvelope;
7890
$id = spl_object_hash($envelope->getMessage());
79-
$this->queue[$id] = $envelope;
91+
$this->queue[$id] = $encodedEnvelope;
8092

8193
return $envelope;
8294
}
@@ -91,22 +103,51 @@ public function reset()
91103
*/
92104
public function getAcknowledged(): array
93105
{
94-
return $this->acknowledged;
106+
return $this->decode($this->acknowledged);
95107
}
96108

97109
/**
98110
* @return Envelope[]
99111
*/
100112
public function getRejected(): array
101113
{
102-
return $this->rejected;
114+
return $this->decode($this->rejected);
103115
}
104116

105117
/**
106118
* @return Envelope[]
107119
*/
108120
public function getSent(): array
109121
{
110-
return $this->sent;
122+
return $this->decode($this->sent);
123+
}
124+
125+
/**
126+
* @return Envelope|array
127+
*/
128+
private function encode(Envelope $envelope)
129+
{
130+
if (null === $this->serializer) {
131+
return $envelope;
132+
}
133+
134+
return $this->serializer->encode($envelope);
135+
}
136+
137+
/**
138+
* @param array<mixed> $messagesEncoded
139+
*
140+
* @return Envelope[]
141+
*/
142+
private function decode(array $messagesEncoded): array
143+
{
144+
if (null === $this->serializer) {
145+
return $messagesEncoded;
146+
}
147+
148+
return array_map(
149+
[$this->serializer, 'decode'],
150+
$messagesEncoded
151+
);
111152
}
112153
}

src/Symfony/Component/Messenger/Transport/InMemoryTransportFactory.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ class InMemoryTransportFactory implements TransportFactoryInterface, ResetInterf
2626

2727
public function createTransport(string $dsn, array $options, SerializerInterface $serializer): TransportInterface
2828
{
29-
return $this->createdTransports[] = new InMemoryTransport();
29+
['serialize' => $serialize] = $this->parseDsn($dsn);
30+
31+
return $this->createdTransports[] = new InMemoryTransport($serialize ? $serializer : null);
3032
}
3133

3234
public function supports(string $dsn, array $options): bool
@@ -40,4 +42,16 @@ public function reset()
4042
$transport->reset();
4143
}
4244
}
45+
46+
private function parseDsn(string $dsn): array
47+
{
48+
$query = [];
49+
if ($queryAsString = strstr($dsn, '?')) {
50+
parse_str(ltrim($queryAsString, '?'), $query);
51+
}
52+
53+
return [
54+
'serialize' => filter_var($query['serialize'] ?? false, \FILTER_VALIDATE_BOOLEAN),
55+
];
56+
}
4357
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy