From cc9867a3641b178b8ba10c683edb19e41e061e3f Mon Sep 17 00:00:00 2001 From: Petr Knap <8299754+petrknap@users.noreply.github.com> Date: Sat, 19 Oct 2024 14:40:44 +0200 Subject: [PATCH] feat: added ability to snapshot on `ProfilerInterface` --- src/Exception/ParentProfileIsNotStarted.php | 2 ++ ...lerCouldNotSnapshotOutsideParentProfile.php | 11 +++++++++++ src/NullProfiler.php | 4 ++++ src/Profiler.php | 5 +++++ src/ProfilerInterface.php | 5 +++++ src/Profiling.php | 8 ++++++++ tests/NullProfilerTest.php | 9 +++++++++ tests/ProfilerTest.php | 18 ++++++++++++++++++ 8 files changed, 62 insertions(+) create mode 100644 src/Exception/ProfilerCouldNotSnapshotOutsideParentProfile.php diff --git a/src/Exception/ParentProfileIsNotStarted.php b/src/Exception/ParentProfileIsNotStarted.php index 5a7fdf3..74ccb9f 100644 --- a/src/Exception/ParentProfileIsNotStarted.php +++ b/src/Exception/ParentProfileIsNotStarted.php @@ -8,6 +8,8 @@ /** * @internal exception should never be thrown out + * + * @todo rename to `ProfilerCouldNotProfileOutsideParentProfile` */ final class ParentProfileIsNotStarted extends LogicException implements ProfilerException { diff --git a/src/Exception/ProfilerCouldNotSnapshotOutsideParentProfile.php b/src/Exception/ProfilerCouldNotSnapshotOutsideParentProfile.php new file mode 100644 index 0000000..aefcc7a --- /dev/null +++ b/src/Exception/ProfilerCouldNotSnapshotOutsideParentProfile.php @@ -0,0 +1,11 @@ + & ProfileWithOutputInterface */ public function profile(callable $callable): ProcessableProfileInterface & ProfileWithOutputInterface; + + /** + * @throws Exception\ProfilerCouldNotSnapshotOutsideParentProfile + */ + public function snapshot(): void; } diff --git a/src/Profiling.php b/src/Profiling.php index 6e83064..f610f2b 100644 --- a/src/Profiling.php +++ b/src/Profiling.php @@ -88,6 +88,14 @@ public function profile(callable $callable): ProcessableProfileInterface & Profi $this->parentProfile->registerTickSnapshot(); } } + + public function snapshot(): void + { + if ($this->parentProfile->getState() !== ProfileState::Started) { + throw new Exception\ProfilerCouldNotSnapshotOutsideParentProfile(); + } + $this->parentProfile->snapshot(); + } }; } diff --git a/tests/NullProfilerTest.php b/tests/NullProfilerTest.php index 035bed9..33058f4 100644 --- a/tests/NullProfilerTest.php +++ b/tests/NullProfilerTest.php @@ -41,4 +41,13 @@ public function testProfileDoesNotRunProcessorAndReturnsCallablesOutput(): void self::assertFalse($processorWasCalled); self::assertSame('output', $output); } + + public function testSnapshotDoesNotThrow(): void + { + $profiler = new NullProfiler(); + + $profiler->snapshot(); + + self::assertTrue(true); + } } diff --git a/tests/ProfilerTest.php b/tests/ProfilerTest.php index 168eaf4..d6ce71f 100644 --- a/tests/ProfilerTest.php +++ b/tests/ProfilerTest.php @@ -37,4 +37,22 @@ public function testReturnsCallablesOutput(): void self::assertSame('output', $profile->getOutput()); } + + public function testSnapshotsOnParentProfile(): void + { + $profiler = new Profiler(); + + $profile = $profiler->profile(static fn (ProfilerInterface $profiler) => $profiler->snapshot()); + + self::assertCount(3, $profile->getMemoryUsages()); + } + + public function testSnapshotsThrowsOutsideProfile(): void + { + $profiler = new Profiler(); + + self::expectException(Exception\ProfilerCouldNotSnapshotOutsideParentProfile::class); + + $profiler->snapshot(); + } }