Skip to content

Commit ac82d7d

Browse files
authored
Merge pull request #14 from symfony/finish-pr-13
Finish pr 13
2 parents ff8b931 + b6c1ecd commit ac82d7d

8 files changed

Lines changed: 231 additions & 10 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ install:
2424
- if [[ $deps = 'low' ]]; then
2525
composer update --prefer-dist --no-progress --no-suggest --prefer-stable --prefer-lowest --ansi;
2626
else
27-
composer update --prefer-dist --no-progress --no-suggest --ansi;
27+
composer update --prefer-dist --no-progress --no-suggest --prefer-stable --ansi;
2828
fi
2929

3030
script:

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
CHANGELOG
22
=========
33

4-
0.1.3
4+
0.2.0
55
-----
66

77
* Compatibility with Symfony 5
8+
* Add a profiler panel
9+
* Autowire `Symfony\Component\Mercure\PublisherInterface` instances (using `Symfony\Component\Mercure\Publisher` for autowiring is deprecated)
810

911
0.1.2
1012
-----

composer.json

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
],
1818
"require": {
1919
"php": "^7.1.3",
20-
"symfony/config": "^3.4|^4.0|^5.0",
21-
"symfony/dependency-injection": "^3.4|^4.0|^5.0",
22-
"symfony/http-kernel": "^3.4|^4.0|^5.0",
23-
"symfony/mercure": "^0.2"
20+
"symfony/config": "^3.4|^4.3|^5.0",
21+
"symfony/dependency-injection": "^3.4|^4.3|^5.0",
22+
"symfony/http-kernel": "^3.4|^4.3|^5.0",
23+
"symfony/mercure": "^0.3"
2424
},
2525
"autoload": {
2626
"psr-4": { "Symfony\\Bundle\\MercureBundle\\": "src/" }
@@ -30,16 +30,19 @@
3030
},
3131
"extra": {
3232
"branch-alias": {
33-
"dev-master": "1.0.x-dev"
33+
"dev-master": "0.2.x-dev"
3434
}
3535
},
3636
"config": {
3737
"sort-packages": true
3838
},
3939
"require-dev": {
40-
"symfony/phpunit-bridge": "^4.2.4|^5.0"
40+
"symfony/phpunit-bridge": "^4.2.4|^5.0",
41+
"symfony/stopwatch": "^3.4|^4.3|^5.0",
42+
"symfony/var-dumper": "^3.4|^4.3|^5.0"
4143
},
4244
"suggest": {
4345
"symfony/messenger": "To use the Messenger integration"
44-
}
46+
},
47+
"minimum-stability": "dev"
4548
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Mercure Component project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
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+
declare(strict_types=1);
13+
14+
namespace Symfony\Bundle\MercureBundle\DataCollector;
15+
16+
use Symfony\Component\HttpFoundation\Request;
17+
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
19+
use Symfony\Component\Mercure\Debug\TraceablePublisher;
20+
21+
final class MercureDataCollector extends DataCollector
22+
{
23+
private $publishers;
24+
25+
/**
26+
* @var TraceablePublisher[]
27+
*/
28+
public function __construct(iterable $publishers)
29+
{
30+
$this->publishers = $publishers;
31+
}
32+
33+
public function collect(Request $request, Response $response, \Exception $exception = null): void
34+
{
35+
$this->data = [
36+
'count' => 0,
37+
'duration' => 0.0,
38+
'memory' => 0,
39+
'publishers' => $this->publishers,
40+
];
41+
42+
foreach ($this->publishers as $name => $publisher) {
43+
$this->data['duration'] += $publisher->getDuration();
44+
$this->data['memory'] += $publisher->getMemory();
45+
$this->data['count'] += \count($publisher->getMessages());
46+
}
47+
}
48+
49+
public function reset(): void
50+
{
51+
$this->data = [];
52+
}
53+
54+
public function getName(): string
55+
{
56+
return 'mercure';
57+
}
58+
59+
public function count(): int
60+
{
61+
return $this->data['count'];
62+
}
63+
64+
public function getDuration(): float
65+
{
66+
return $this->data['duration'];
67+
}
68+
69+
public function getMemory(): int
70+
{
71+
return $this->data['memory'];
72+
}
73+
74+
/**
75+
* @return TraceablePublisher[]
76+
*/
77+
public function getPublishers(): iterable
78+
{
79+
return $this->data['publishers'];
80+
}
81+
}

src/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public function getConfigTreeBuilder(): TreeBuilder
5050
->end()
5151
->end()
5252
->scalarNode('default_hub')->end()
53+
->booleanNode('enable_profiler')->info('Enable Symfony Web Profiler integration.')->defaultFalse()->end()
5354
->end()
5455
->end()
5556
;

src/DependencyInjection/MercureExtension.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,18 @@
1313

1414
namespace Symfony\Bundle\MercureBundle\DependencyInjection;
1515

16+
use Symfony\Bundle\MercureBundle\DataCollector\MercureDataCollector;
1617
use Symfony\Component\Config\Definition\ConfigurationInterface;
18+
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1719
use Symfony\Component\DependencyInjection\ContainerBuilder;
1820
use Symfony\Component\DependencyInjection\ContainerInterface;
1921
use Symfony\Component\DependencyInjection\Reference;
2022
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
23+
use Symfony\Component\Mercure\Debug\TraceablePublisher;
2124
use Symfony\Component\Mercure\Jwt\StaticJwtProvider;
2225
use Symfony\Component\Mercure\Publisher;
26+
use Symfony\Component\Mercure\PublisherInterface;
27+
use Symfony\Component\Stopwatch\Stopwatch;
2328

2429
/**
2530
* @author Kévin Dunglas <dunglas@gmail.com>
@@ -43,7 +48,9 @@ public function load(array $configs, ContainerBuilder $container)
4348

4449
$defaultHub = $config['default_hub'] ?? null;
4550
$hubUrls = [];
51+
$publishers = [];
4652
$defaultHubUrl = null;
53+
$enableProfiler = $config['enable_profiler'] && class_exists(Stopwatch::class);
4754
foreach ($config['hubs'] as $name => $hub) {
4855
if (isset($hub['jwt'])) {
4956
$jwtProvider = sprintf('mercure.hub.%s.jwt_provider', $name);
@@ -67,9 +74,32 @@ public function load(array $configs, ContainerBuilder $container)
6774
$bus = $hub['bus'] ?? null;
6875
$attributes = null === $bus ? [] : ['bus' => $hub['bus']];
6976
$publisherDefinition->addTag('messenger.message_handler', $attributes);
77+
78+
if ($enableProfiler) {
79+
$container->register("$hubId.traceable", TraceablePublisher::class)
80+
->setDecoratedService($hubId)
81+
->addArgument(new Reference("$hubId.traceable.inner"))
82+
->addArgument(new Reference('debug.stopwatch'));
83+
84+
$publishers[$name] = new Reference("$hubId.traceable");
85+
}
86+
}
87+
88+
if ($enableProfiler) {
89+
$container->register('data_collector.mercure', MercureDataCollector::class)
90+
->addArgument(new IteratorArgument($publishers))
91+
->addTag('data_collector', [
92+
'template' => '@Mercure/Collector/mercure.html.twig',
93+
'id' => 'mercure',
94+
]);
95+
}
96+
97+
$alias = $container->setAlias(Publisher::class, $defaultHub);
98+
if (method_exists($alias, 'setDeprecated')) {
99+
$alias->setDeprecated(true, 'The "%alias_id%" service alias is deprecated. Use "'.PublisherInterface::class.'" instead.');
70100
}
71101

72-
$container->setAlias(Publisher::class, $defaultHub);
102+
$container->setAlias(PublisherInterface::class, $defaultHub);
73103
$container->setParameter('mercure.hubs', $hubUrls);
74104
$container->setParameter('mercure.default_hub', $defaultHubUrl);
75105
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
2+
3+
{% import _self as helper %}
4+
5+
{% block toolbar %}
6+
{% if collector.count > 0 %}
7+
{% set icon %}
8+
{{ include('@Mercure/Icon/mercure.svg') }}
9+
<span class="sf-toolbar-value">{{ collector.count }}</span>
10+
{% endset %}
11+
12+
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: 'mercure' }) }}
13+
{% endif %}
14+
{% endblock %}
15+
16+
{% block menu %}
17+
<span class="label{{ collector.count == 0 ? ' disabled' }}">
18+
<span class="icon">{{ include('@Mercure/Icon/mercure.svg') }}</span>
19+
<strong>Mercure</strong>
20+
</span>
21+
{% endblock %}
22+
23+
{% block panel %}
24+
{% import _self as helper %}
25+
26+
<h2>Messages</h2>
27+
28+
{% if collector.count == 0 %}
29+
<div class="empty">
30+
<p>No messages have been collected.</p>
31+
</div>
32+
{% else %}
33+
<div class="sf-tabs">
34+
{% for hub, publisher in collector.publishers %}
35+
<div class="tab">
36+
<h3 class="tab-title">{{ hub }}<span class="badge">{{ publisher.count }}</span></h3>
37+
<div class="tab-content">
38+
<div class="metrics">
39+
<div class="metric">
40+
<span class="value">{{ '%.0f'|format(publisher.duration) }} <span class="unit">ms</span></span>
41+
<span class="label">Total execution time</span>
42+
</div>
43+
<div class="metric">
44+
<span class="value">{{ '%.2f'|format(publisher.memory / 1024 / 1024) }} <span class="unit">MB</span></span>
45+
<span class="label">Peak memory usage</span>
46+
</div>
47+
</div>
48+
49+
<table>
50+
<thead>
51+
<tr>
52+
<th>#</th>
53+
<th>Time</th>
54+
<th>Memory</th>
55+
<th>Topics</th>
56+
<th>Data</th>
57+
<th>Targets</th>
58+
<th>ID</th>
59+
<th>Type</th>
60+
<th>Retry</th>
61+
</tr>
62+
</thead>
63+
{% for i, message in publisher.messages %}
64+
<tr>
65+
<td class="font-normal text-small text-muted nowrap">{{ i + 1 }}</td>
66+
<td class="nowrap">{{ '%.0f'|format(message.duration) }} ms</td>
67+
<td class="nowrap">{{ '%.2f'|format(message.memory / 1024 / 1024) }} MB</td>
68+
<td class="font-normal text-small text-bold nowrap">{{ message.object.topics|join(',') }}</td>
69+
<td>{{ dump(message.object.data) }}</td>
70+
<td class="font-normal text-small text-bold nowrap">{{ message.object.targets|join(',') }}</td>
71+
<td class="nowrap">{{ message.object.id }}</td>
72+
<td class="nowrap">{{ message.object.type }}</td>
73+
<td class="nowrap">{{ message.object.retry }}</td>
74+
</tr>
75+
{% endfor %}
76+
</table>
77+
</div>
78+
</div>
79+
{% endfor %}
80+
</div>
81+
{% endif %}
82+
{% endblock %}
Lines changed: 22 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)