Skip to content

Commit e29bcf3

Browse files
vjikxepozz
andauthored
Debugger: minor refactoring and phpdoc (#305)
Co-authored-by: Dmitriy Derepko <xepozz@list.ru>
1 parent c578957 commit e29bcf3

6 files changed

Lines changed: 95 additions & 44 deletions

File tree

config/events-console.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717

1818
return [
1919
ApplicationStartup::class => [
20-
[Debugger::class, 'startup'],
20+
[Debugger::class, 'start'],
2121
[ConsoleAppInfoCollector::class, 'collect'],
2222
],
2323
ApplicationShutdown::class => [
2424
[ConsoleAppInfoCollector::class, 'collect'],
25-
[Debugger::class, 'shutdown'],
25+
[Debugger::class, 'stop'],
2626
],
2727
ConsoleCommandEvent::class => [
2828
[ConsoleAppInfoCollector::class, 'collect'],

config/events-web.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020

2121
return [
2222
ApplicationStartup::class => [
23-
[Debugger::class, 'startup'],
23+
[Debugger::class, 'start'],
2424
[WebAppInfoCollector::class, 'collect'],
2525
],
2626
ApplicationShutdown::class => [
2727
[WebAppInfoCollector::class, 'collect'],
2828
],
2929
BeforeRequest::class => [
30-
[Debugger::class, 'startup'],
30+
[Debugger::class, 'start'],
3131
[WebAppInfoCollector::class, 'collect'],
3232
[RequestCollector::class, 'collect'],
3333
],
@@ -38,7 +38,7 @@
3838
AfterEmit::class => [
3939
[ProfilerInterface::class, 'flush'],
4040
[WebAppInfoCollector::class, 'collect'],
41-
[Debugger::class, 'shutdown'],
41+
[Debugger::class, 'stop'],
4242
],
4343
ApplicationError::class => [
4444
[ExceptionCollector::class, 'collect'],

src/Collector/CollectorInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function startup(): void;
2222

2323
/**
2424
* Called once at application shutdown.
25-
* Cleanup could be done here.
25+
* Cleanup could be done here. Implementation must be idempotent.
2626
*/
2727
public function shutdown(): void;
2828

src/Command/DebugResetCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected function configure(): void
3333

3434
protected function execute(InputInterface $input, OutputInterface $output): int
3535
{
36-
$this->debugger->stop();
36+
$this->debugger->kill();
3737
$this->storage->clear();
3838

3939
return ExitCode::OK;

src/Debugger.php

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,31 @@
1313
use Yiisoft\Yii\Debug\StartupPolicy\Debugger\DebuggerStartupPolicyInterface;
1414
use Yiisoft\Yii\Debug\Storage\StorageInterface;
1515

16+
/**
17+
* Debugger collects data from collectors and stores it in a storage.
18+
*/
1619
final class Debugger
1720
{
1821
/**
22+
* @var CollectorInterface[] Collectors, indexed by their names.
23+
*
1924
* @psalm-var array<string, CollectorInterface>
2025
*/
2126
private readonly array $collectors;
22-
private readonly DataNormalizer $dataNormalizer;
2327

2428
/**
25-
* @var string|null ID of the current request. Null if debugger is not active.
29+
* @var DataNormalizer Data normalizer that prepares data for storage.
2630
*/
27-
private ?string $id = null;
31+
private readonly DataNormalizer $dataNormalizer;
2832

2933
/**
30-
* @param CollectorInterface[] $collectors
34+
* @param StorageInterface $storage The storage to store collected data.
35+
* @param CollectorInterface[] $collectors Collectors to be used.
36+
* @param DebuggerStartupPolicyInterface $debuggerStartupPolicy Policy to decide whether debugger should be started.
37+
* Default {@see AlwaysOnDebuggerPolicy} that always allows to startup debugger.
38+
* @param CollectorStartupPolicyInterface $collectorStartupPolicy Policy to decide whether collector should be
39+
* started. Default {@see AllowAllCollectorPolicy} that always allows to use all collectors.
40+
* @param array $excludedClasses List of classes to be excluded from collected data before storing.
3141
*/
3242
public function __construct(
3343
private readonly StorageInterface $storage,
@@ -44,20 +54,42 @@ public function __construct(
4454

4555
$this->dataNormalizer = new DataNormalizer($excludedClasses);
4656

47-
register_shutdown_function([$this, 'shutdown']);
57+
register_shutdown_function([$this, 'stop']);
4858
}
4959

60+
/**
61+
* @var string|null ID of the current request. `null` if debugger is not active.
62+
*/
63+
private ?string $id = null;
64+
65+
/**
66+
* Returns whether debugger is active.
67+
*
68+
* @return bool Whether debugger is active.
69+
*/
5070
public function isActive(): bool
5171
{
5272
return $this->id !== null;
5373
}
5474

75+
/**
76+
* Returns ID of the current request.
77+
*
78+
* Throws `LogicException` if debugger is not started. Use {@see isActive()} to check if debugger is active.
79+
*
80+
* @return string ID of the current request.
81+
*/
5582
public function getId(): string
5683
{
5784
return $this->id ?? throw new LogicException('Debugger is not started.');
5885
}
5986

60-
public function startup(object $event): void
87+
/**
88+
* Starts debugger and collectors.
89+
*
90+
* @param object $event Event that triggered debugger startup.
91+
*/
92+
public function start(object $event): void
6193
{
6294
if (!$this->debuggerStartupPolicy->satisfies($event)) {
6395
return;
@@ -72,39 +104,58 @@ public function startup(object $event): void
72104
}
73105
}
74106

75-
public function shutdown(): void
107+
/**
108+
* Stops the debugger for listening. Collected data will be flushed to storage.
109+
*/
110+
public function stop(): void
76111
{
77112
if (!$this->isActive()) {
78113
return;
79114
}
80115

81116
try {
82-
$collectedData = array_map(
83-
static fn (CollectorInterface $collector) => $collector->getCollected(),
84-
$this->collectors
85-
);
86-
87-
/** @var array[] $data */
88-
[$data, $objectsMap] = $this->dataNormalizer->prepareDataAndObjectsMap($collectedData, 30);
89-
90-
/** @var array $summary */
91-
$summary = $this->dataNormalizer->prepareData($this->collectSummaryData(), 30);
92-
93-
$this->storage->write($this->getId(), $data, $objectsMap, $summary);
117+
$this->flush();
94118
} finally {
95-
foreach ($this->collectors as $collector) {
96-
$collector->shutdown();
97-
}
98-
$this->id = null;
119+
$this->deactivate();
99120
}
100121
}
101122

102-
public function stop(): void
123+
/**
124+
* Stops the debugger from listening. Collected data will not be flushed to storage.
125+
*/
126+
public function kill(): void
103127
{
104128
if (!$this->isActive()) {
105129
return;
106130
}
107131

132+
$this->deactivate();
133+
}
134+
135+
/**
136+
* Collects data from collectors and stores it in a storage.
137+
*/
138+
private function flush(): void
139+
{
140+
$collectedData = array_map(
141+
static fn (CollectorInterface $collector) => $collector->getCollected(),
142+
$this->collectors
143+
);
144+
145+
/** @var array[] $data */
146+
[$data, $objectsMap] = $this->dataNormalizer->prepareDataAndObjectsMap($collectedData, 30);
147+
148+
/** @var array $summary */
149+
$summary = $this->dataNormalizer->prepareData($this->collectSummaryData(), 30);
150+
151+
$this->storage->write($this->getId(), $data, $objectsMap, $summary);
152+
}
153+
154+
/**
155+
* Stops debugger and collectors.
156+
*/
157+
private function deactivate(): void
158+
{
108159
foreach ($this->collectors as $collector) {
109160
$collector->shutdown();
110161
}

tests/Unit/DebuggerTest.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,31 @@
1616

1717
final class DebuggerTest extends TestCase
1818
{
19-
public function testStartup(): void
19+
public function testStart(): void
2020
{
2121
$collector = $this->getMockBuilder(CollectorInterface::class)->getMock();
2222
$collector->expects($this->once())->method('startup');
2323
$storage = new MemoryStorage();
2424

2525
$debugger = new Debugger($storage, [$collector]);
26-
$debugger->startup(new stdClass());
26+
$debugger->start(new stdClass());
2727
}
2828

29-
public function testShutdown(): void
29+
public function testStop(): void
3030
{
3131
$collector = $this->getMockBuilder(CollectorInterface::class)->getMock();
3232
$collector->expects($this->once())->method('shutdown');
3333
$storage = $this->getMockBuilder(StorageInterface::class)->getMock();
3434
$storage->expects($this->once())->method('write');
3535

3636
$debugger = new Debugger($storage, [$collector]);
37-
$debugger->startup(new BeforeRequest(new ServerRequest('GET', '/test')));
38-
$debugger->shutdown();
39-
$debugger->shutdown();
40-
$debugger->shutdown();
37+
$debugger->start(new BeforeRequest(new ServerRequest('GET', '/test')));
38+
$debugger->stop();
39+
$debugger->stop();
40+
$debugger->stop();
4141
}
4242

43-
public function testShutdownWithStartupPrevention(): void
43+
public function testStopWithStartupPrevention(): void
4444
{
4545
$collector = $this->getMockBuilder(CollectorInterface::class)->getMock();
4646
$collector->expects($this->never())->method('startup');
@@ -50,8 +50,8 @@ public function testShutdownWithStartupPrevention(): void
5050
$storage->expects($this->never())->method('write');
5151

5252
$debugger = new Debugger($storage, [$collector], new AllowDebuggerPolicy());
53-
$debugger->startup(new BeforeRequest(new ServerRequest('GET', '/test')));
54-
$debugger->shutdown();
53+
$debugger->start(new BeforeRequest(new ServerRequest('GET', '/test')));
54+
$debugger->stop();
5555
}
5656

5757
public function testStopSkipped(): void
@@ -63,8 +63,8 @@ public function testStopSkipped(): void
6363
$storage->expects($this->never())->method('write');
6464

6565
$debugger = new Debugger($storage, [$collector]);
66-
$debugger->startup(new BeforeRequest(new ServerRequest('GET', '/test')));
67-
$debugger->stop();
68-
$debugger->stop();
66+
$debugger->start(new BeforeRequest(new ServerRequest('GET', '/test')));
67+
$debugger->kill();
68+
$debugger->kill();
6969
}
7070
}

0 commit comments

Comments
 (0)