Skip to content

Commit 29733e4

Browse files
ogizanagifabpot
authored andcommitted
[Messenger] Improve the profiler panel
1 parent fa76a83 commit 29733e4

File tree

6 files changed

+174
-64
lines changed

6 files changed

+174
-64
lines changed

DataCollector/MessengerDataCollector.php

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
1717
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
1818
use Symfony\Component\Messenger\TraceableMessageBus;
19+
use Symfony\Component\VarDumper\Caster\ClassStub;
20+
use Symfony\Component\VarDumper\Cloner\Data;
1921

2022
/**
2123
* @author Samuel Roze <[email protected]>
@@ -44,13 +46,25 @@ public function collect(Request $request, Response $response, \Exception $except
4446
*/
4547
public function lateCollect()
4648
{
47-
$this->data = array('messages' => array());
49+
$this->data = array('messages' => array(), 'buses' => array_keys($this->traceableBuses));
4850

51+
$messages = array();
4952
foreach ($this->traceableBuses as $busName => $bus) {
5053
foreach ($bus->getDispatchedMessages() as $message) {
51-
$this->data['messages'][] = $this->collectMessage($busName, $message);
54+
$debugRepresentation = $this->cloneVar($this->collectMessage($busName, $message));
55+
$messages[] = array($debugRepresentation, $message['callTime']);
5256
}
5357
}
58+
59+
// Order by call time
60+
usort($messages, function (array $a, array $b): int {
61+
return $a[1] > $b[1] ? 1 : -1;
62+
});
63+
64+
// Keep the messages clones only
65+
$this->data['messages'] = array_map(function (array $item): Data {
66+
return $item[0];
67+
}, $messages);
5468
}
5569

5670
/**
@@ -78,47 +92,51 @@ private function collectMessage(string $busName, array $tracedMessage)
7892

7993
$debugRepresentation = array(
8094
'bus' => $busName,
95+
'envelopeItems' => $tracedMessage['envelopeItems'] ?? null,
8196
'message' => array(
82-
'type' => \get_class($message),
83-
'object' => $this->cloneVar($message),
97+
'type' => new ClassStub(\get_class($message)),
98+
'value' => $message,
8499
),
85100
);
86101

87102
if (array_key_exists('result', $tracedMessage)) {
88103
$result = $tracedMessage['result'];
89-
90-
if (\is_object($result)) {
91-
$debugRepresentation['result'] = array(
92-
'type' => \get_class($result),
93-
'object' => $this->cloneVar($result),
94-
);
95-
} elseif (\is_array($result)) {
96-
$debugRepresentation['result'] = array(
97-
'type' => 'array',
98-
'object' => $this->cloneVar($result),
99-
);
100-
} else {
101-
$debugRepresentation['result'] = array(
102-
'type' => \gettype($result),
103-
'value' => $result,
104-
);
105-
}
104+
$debugRepresentation['result'] = array(
105+
'type' => \is_object($result) ? \get_class($result) : gettype($result),
106+
'value' => $result,
107+
);
106108
}
107109

108110
if (isset($tracedMessage['exception'])) {
109111
$exception = $tracedMessage['exception'];
110112

111113
$debugRepresentation['exception'] = array(
112114
'type' => \get_class($exception),
113-
'message' => $exception->getMessage(),
115+
'value' => $exception,
114116
);
115117
}
116118

117119
return $debugRepresentation;
118120
}
119121

120-
public function getMessages(): array
122+
public function getExceptionsCount(string $bus = null): int
123+
{
124+
return array_reduce($this->getMessages($bus), function (int $carry, Data $message) {
125+
return $carry += isset($message['exception']) ? 1 : 0;
126+
}, 0);
127+
}
128+
129+
public function getMessages(string $bus = null): array
130+
{
131+
$messages = $this->data['messages'] ?? array();
132+
133+
return $bus ? array_filter($messages, function (Data $message) use ($bus): bool {
134+
return $bus === $message['bus'];
135+
}) : $messages;
136+
}
137+
138+
public function getBuses(): array
121139
{
122-
return $this->data['messages'] ?? array();
140+
return $this->data['buses'];
123141
}
124142
}

Tests/DataCollector/MessengerDataCollectorTest.php

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,22 @@
1616
use Symfony\Component\Messenger\MessageBusInterface;
1717
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
1818
use Symfony\Component\Messenger\TraceableMessageBus;
19-
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
19+
use Symfony\Component\VarDumper\Cloner\Data;
20+
use Symfony\Component\VarDumper\Dumper\CliDumper;
2021

2122
/**
2223
* @author Maxime Steinhausser <[email protected]>
2324
*/
2425
class MessengerDataCollectorTest extends TestCase
2526
{
26-
use VarDumperTestTrait;
27+
/** @var CliDumper */
28+
private $dumper;
29+
30+
protected function setUp()
31+
{
32+
$this->dumper = new CliDumper();
33+
$this->dumper->setColors(false);
34+
}
2735

2836
/**
2937
* @dataProvider getHandleTestData
@@ -46,25 +54,26 @@ public function testHandle($returnedValue, $expected)
4654
$messages = $collector->getMessages();
4755
$this->assertCount(1, $messages);
4856

49-
$this->assertDumpMatchesFormat($expected, $messages[0]);
57+
$this->assertStringMatchesFormat($expected, $this->getDataAsString($messages[0]));
5058
}
5159

5260
public function getHandleTestData()
5361
{
5462
$messageDump = <<<DUMP
5563
"bus" => "default"
64+
"envelopeItems" => null
5665
"message" => array:2 [
5766
"type" => "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"
58-
"object" => Symfony\Component\VarDumper\Cloner\Data {%A
59-
%A+class: "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"%A
67+
"value" => Symfony\Component\Messenger\Tests\Fixtures\DummyMessage %A
68+
-message: "dummy message"
6069
}
6170
]
6271
DUMP;
6372

6473
yield 'no returned value' => array(
6574
null,
6675
<<<DUMP
67-
array:3 [
76+
array:4 [
6877
$messageDump
6978
"result" => array:2 [
7079
"type" => "NULL"
@@ -77,7 +86,7 @@ public function getHandleTestData()
7786
yield 'scalar returned value' => array(
7887
'returned value',
7988
<<<DUMP
80-
array:3 [
89+
array:4 [
8190
$messageDump
8291
"result" => array:2 [
8392
"type" => "string"
@@ -90,11 +99,13 @@ public function getHandleTestData()
9099
yield 'array returned value' => array(
91100
array('returned value'),
92101
<<<DUMP
93-
array:3 [
102+
array:4 [
94103
$messageDump
95104
"result" => array:2 [
96105
"type" => "array"
97-
"object" => Symfony\Component\VarDumper\Cloner\Data {%A
106+
"value" => array:1 [
107+
0 => "returned value"
108+
]
98109
]
99110
]
100111
DUMP
@@ -123,21 +134,66 @@ public function testHandleWithException()
123134
$messages = $collector->getMessages();
124135
$this->assertCount(1, $messages);
125136

126-
$this->assertDumpMatchesFormat(<<<DUMP
127-
array:3 [
137+
$this->assertStringMatchesFormat(<<<DUMP
138+
array:4 [
128139
"bus" => "default"
140+
"envelopeItems" => null
129141
"message" => array:2 [
130142
"type" => "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"
131-
"object" => Symfony\Component\VarDumper\Cloner\Data {%A
132-
%A+class: "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"%A
143+
"value" => Symfony\Component\Messenger\Tests\Fixtures\DummyMessage %A
144+
-message: "dummy message"
133145
}
134146
]
135147
"exception" => array:2 [
136148
"type" => "RuntimeException"
137-
"message" => "foo"
149+
"value" => RuntimeException %A
138150
]
139-
]
151+
]
140152
DUMP
141-
, $messages[0]);
153+
, $this->getDataAsString($messages[0]));
154+
}
155+
156+
public function testKeepsOrderedDispatchCalls()
157+
{
158+
$firstBus = $this->getMockBuilder(MessageBusInterface::class)->getMock();
159+
$firstBus = new TraceableMessageBus($firstBus);
160+
161+
$secondBus = $this->getMockBuilder(MessageBusInterface::class)->getMock();
162+
$secondBus = new TraceableMessageBus($secondBus);
163+
164+
$collector = new MessengerDataCollector();
165+
$collector->registerBus('first bus', $firstBus);
166+
$collector->registerBus('second bus', $secondBus);
167+
168+
$firstBus->dispatch(new DummyMessage('#1'));
169+
$secondBus->dispatch(new DummyMessage('#2'));
170+
$secondBus->dispatch(new DummyMessage('#3'));
171+
$firstBus->dispatch(new DummyMessage('#4'));
172+
$secondBus->dispatch(new DummyMessage('#5'));
173+
174+
$collector->lateCollect();
175+
176+
$messages = $collector->getMessages();
177+
$this->assertCount(5, $messages);
178+
179+
$this->assertSame('#1', $messages[0]['message']['value']['message']);
180+
$this->assertSame('first bus', $messages[0]['bus']);
181+
182+
$this->assertSame('#2', $messages[1]['message']['value']['message']);
183+
$this->assertSame('second bus', $messages[1]['bus']);
184+
185+
$this->assertSame('#3', $messages[2]['message']['value']['message']);
186+
$this->assertSame('second bus', $messages[2]['bus']);
187+
188+
$this->assertSame('#4', $messages[3]['message']['value']['message']);
189+
$this->assertSame('first bus', $messages[3]['bus']);
190+
191+
$this->assertSame('#5', $messages[4]['message']['value']['message']);
192+
$this->assertSame('second bus', $messages[4]['bus']);
193+
}
194+
195+
private function getDataAsString(Data $data): string
196+
{
197+
return rtrim($this->dumper->dump($data, true));
142198
}
143199
}

Tests/Fixtures/AnEnvelopeItem.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Tests\Fixtures;
13+
14+
use Symfony\Component\Messenger\EnvelopeItemInterface;
15+
16+
class AnEnvelopeItem implements EnvelopeItemInterface
17+
{
18+
/**
19+
* {@inheritdoc}
20+
*/
21+
public function serialize()
22+
{
23+
return '';
24+
}
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function unserialize($serialized)
30+
{
31+
// noop
32+
}
33+
}

Tests/MessageBusTest.php

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
1616
use Symfony\Component\Messenger\Envelope;
1717
use Symfony\Component\Messenger\EnvelopeAwareInterface;
18-
use Symfony\Component\Messenger\EnvelopeItemInterface;
1918
use Symfony\Component\Messenger\MessageBus;
2019
use Symfony\Component\Messenger\MessageBusInterface;
2120
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
21+
use Symfony\Component\Messenger\Tests\Fixtures\AnEnvelopeItem;
2222
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
2323

2424
class MessageBusTest extends TestCase
@@ -160,22 +160,3 @@ public function testThatAMiddlewareCanUpdateTheMessageWhileKeepingTheEnvelopeIte
160160
$bus->dispatch($envelope);
161161
}
162162
}
163-
164-
class AnEnvelopeItem implements EnvelopeItemInterface
165-
{
166-
/**
167-
* {@inheritdoc}
168-
*/
169-
public function serialize()
170-
{
171-
return '';
172-
}
173-
174-
/**
175-
* {@inheritdoc}
176-
*/
177-
public function unserialize($serialized)
178-
{
179-
return new self();
180-
}
181-
}

Tests/TraceableMessageBusTest.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Messenger\Envelope;
1616
use Symfony\Component\Messenger\MessageBusInterface;
17+
use Symfony\Component\Messenger\Tests\Fixtures\AnEnvelopeItem;
1718
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
1819
use Symfony\Component\Messenger\TraceableMessageBus;
1920

@@ -28,19 +29,29 @@ public function testItTracesResult()
2829

2930
$traceableBus = new TraceableMessageBus($bus);
3031
$this->assertSame($result, $traceableBus->dispatch($message));
31-
$this->assertSame(array(array('message' => $message, 'result' => $result)), $traceableBus->getDispatchedMessages());
32+
$this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages());
33+
$this->assertArraySubset(array(
34+
'message' => $message,
35+
'result' => $result,
36+
'envelopeItems' => null,
37+
), $tracedMessages[0], true);
3238
}
3339

3440
public function testItTracesResultWithEnvelope()
3541
{
36-
$envelope = Envelope::wrap($message = new DummyMessage('Hello'));
42+
$envelope = Envelope::wrap($message = new DummyMessage('Hello'))->with($envelopeItem = new AnEnvelopeItem());
3743

3844
$bus = $this->getMockBuilder(MessageBusInterface::class)->getMock();
3945
$bus->expects($this->once())->method('dispatch')->with($envelope)->willReturn($result = array('foo' => 'bar'));
4046

4147
$traceableBus = new TraceableMessageBus($bus);
4248
$this->assertSame($result, $traceableBus->dispatch($envelope));
43-
$this->assertSame(array(array('message' => $message, 'result' => $result)), $traceableBus->getDispatchedMessages());
49+
$this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages());
50+
$this->assertArraySubset(array(
51+
'message' => $message,
52+
'result' => $result,
53+
'envelopeItems' => array($envelopeItem),
54+
), $tracedMessages[0], true);
4455
}
4556

4657
public function testItTracesExceptions()
@@ -58,6 +69,11 @@ public function testItTracesExceptions()
5869
$this->assertSame($exception, $e);
5970
}
6071

61-
$this->assertSame(array(array('message' => $message, 'exception' => $exception)), $traceableBus->getDispatchedMessages());
72+
$this->assertCount(1, $tracedMessages = $traceableBus->getDispatchedMessages());
73+
$this->assertArraySubset(array(
74+
'message' => $message,
75+
'exception' => $exception,
76+
'envelopeItems' => null,
77+
), $tracedMessages[0], true);
6278
}
6379
}

0 commit comments

Comments
 (0)