diff --git a/CHANGELOG.md b/CHANGELOG.md index 908cb32..36d0f88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [Unreleased] + +### Added + +- `Innmind\OperatingSystem\Config::handleSignalsVia()` + +### Changed + +- Requires `innmind/signals:~4.0` + ## 6.1.0 - 2025-08-17 ### Added diff --git a/composer.json b/composer.json index eb4ac8c..67b02d7 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "innmind/filesystem": "~8.1", "innmind/http-transport": "~8.0", "innmind/time-warp": "~4.0", - "innmind/signals": "~3.0", + "innmind/signals": "~4.0", "innmind/file-watch": "~5.0", "formal/access-layer": "~4.0", "innmind/io": "~3.2", diff --git a/src/Config.php b/src/Config.php index afdf2f4..69e7c29 100644 --- a/src/Config.php +++ b/src/Config.php @@ -16,6 +16,7 @@ }; use Innmind\FileWatch\Watch; use Innmind\Server\Status\EnvironmentPath; +use Innmind\Signals\Handler; use Innmind\TimeWarp\Halt; use Innmind\IO\IO; use Innmind\Url\{ @@ -55,6 +56,7 @@ private function __construct( private \Closure $mapFileWatch, private \Closure $filesystem, private \Closure $mapFilesystem, + private Handler $signals, ) { } @@ -86,6 +88,7 @@ public static function new(): self )->withCaseSensitivity(CaseSensitivity::sensitive), ), static fn(Filesystem $filesystem, self $config) => $filesystem, + Handler::main(), ); } @@ -121,6 +124,7 @@ public function withClock(Clock $clock): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -152,6 +156,7 @@ public function mapClock(\Closure $map): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -176,6 +181,7 @@ public function haltProcessVia(Halt $halt): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -208,6 +214,7 @@ public function mapHalt(\Closure $map): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -232,6 +239,7 @@ public function withIO(IO $io): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -256,6 +264,7 @@ public function withEnvironmentPath(EnvironmentPath $path): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -280,6 +289,7 @@ public function useHttpTransport(HttpTransport $transport): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -311,6 +321,7 @@ public function mapHttpTransport(\Closure $map): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -337,6 +348,7 @@ public function openSQLConnectionVia(\Closure $sql): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -368,6 +380,7 @@ public function mapSQLConnection(\Closure $map): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -399,6 +412,7 @@ public function mapServerControl(\Closure $map): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -430,6 +444,7 @@ public function mapServerStatus(\Closure $map): self $this->mapFileWatch, $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -461,6 +476,7 @@ public function mapFileWatch(\Closure $map): self ), $this->filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -487,6 +503,7 @@ public function mountFilesystemVia(\Closure $filesystem): self $this->mapFileWatch, $filesystem, $this->mapFilesystem, + $this->signals, ); } @@ -518,6 +535,32 @@ public function mapFilesystem(\Closure $map): self $previous($filesystem, $config), $config, ), + $this->signals, + ); + } + + /** + * @psalm-mutation-free + */ + public function handleSignalsVia(Handler $handler): self + { + return new self( + $this->clock, + $this->mapClock, + $this->io, + $this->halt, + $this->mapHalt, + $this->path, + $this->httpTransport, + $this->mapHttpTransport, + $this->sql, + $this->mapSql, + $this->mapServerControl, + $this->mapServerStatus, + $this->mapFileWatch, + $this->filesystem, + $this->mapFilesystem, + $handler, ); } @@ -612,4 +655,12 @@ public function fileWatch(Watch $watch): Watch { return ($this->mapFileWatch)($watch, $this); } + + /** + * @internal + */ + public function signalsHandler(): Handler + { + return $this->signals; + } } diff --git a/src/CurrentProcess.php b/src/CurrentProcess.php index fa2d194..eb3a433 100644 --- a/src/CurrentProcess.php +++ b/src/CurrentProcess.php @@ -8,6 +8,7 @@ use Innmind\Server\Status\Server\Memory\Bytes; use Innmind\TimeContinuum\Period; use Innmind\TimeWarp\Halt; +use Innmind\Signals\Handler; use Innmind\Immutable\{ Attempt, SideEffect, @@ -16,19 +17,21 @@ final class CurrentProcess { private Halt $halt; + private Handler $handler; private ?Signals $signals = null; - private function __construct(Halt $halt) + private function __construct(Halt $halt, Handler $handler) { $this->halt = $halt; + $this->handler = $handler; } /** * @internal */ - public static function of(Halt $halt): self + public static function of(Halt $halt, Handler $handler): self { - return new self($halt); + return new self($halt, $handler); } /** @@ -47,7 +50,7 @@ public function id(): Attempt public function signals(): Signals { - return $this->signals ??= Signals::of(); + return $this->signals ??= Signals::of($this->handler); } /** diff --git a/src/CurrentProcess/Signals.php b/src/CurrentProcess/Signals.php index a22d7d9..1a5c961 100644 --- a/src/CurrentProcess/Signals.php +++ b/src/CurrentProcess/Signals.php @@ -21,9 +21,9 @@ private function __construct(Handler $handler) /** * @internal */ - public static function of(): self + public static function of(Handler $handler): self { - return new self(new Handler); + return new self($handler); } /** diff --git a/src/OperatingSystem.php b/src/OperatingSystem.php index 406f7d0..a9ebd2a 100644 --- a/src/OperatingSystem.php +++ b/src/OperatingSystem.php @@ -100,6 +100,9 @@ public function remote(): Remote public function process(): CurrentProcess { - return $this->process ??= CurrentProcess::of($this->config->halt()); + return $this->process ??= CurrentProcess::of( + $this->config->halt(), + $this->config->signalsHandler(), + ); } } diff --git a/tests/CurrentProcess/SignalsTest.php b/tests/CurrentProcess/SignalsTest.php index a3130ec..54c7c19 100644 --- a/tests/CurrentProcess/SignalsTest.php +++ b/tests/CurrentProcess/SignalsTest.php @@ -14,7 +14,7 @@ class SignalsTest extends TestCase { public function testListen() { - $signals = Signals::of(new Handler); + $signals = Signals::of(Handler::main()); $order = []; $count = 0; @@ -39,7 +39,7 @@ public function testListen() public function testRemoveSignal() { - $signals = Signals::of(new Handler); + $signals = Signals::of(Handler::main()); $order = []; $count = 0; diff --git a/tests/CurrentProcessTest.php b/tests/CurrentProcessTest.php index 5b819d6..ca7b1a3 100644 --- a/tests/CurrentProcessTest.php +++ b/tests/CurrentProcessTest.php @@ -13,6 +13,11 @@ use Innmind\Server\Status\Server\Memory\Bytes; use Innmind\TimeContinuum\Period; use Innmind\TimeWarp\Halt; +use Innmind\Signals\{ + Handler, + Signal, + Async\Interceptor, +}; use Innmind\Immutable\SideEffect; use Psr\Log\NullLogger; use Innmind\BlackBox\{ @@ -27,7 +32,10 @@ class CurrentProcessTest extends TestCase public function testId() { - $process = CurrentProcess::of(Halt\Usleep::new()); + $process = CurrentProcess::of( + Halt\Usleep::new(), + Handler::main(), + ); $this->assertInstanceOf(Pid::class, $process->id()->unwrap()); $this->assertSame( @@ -57,15 +65,45 @@ public function testHalt(): BlackBox\Proof public function testSignals() { - $process = CurrentProcess::of(Halt\Usleep::new()); + $process = CurrentProcess::of( + Halt\Usleep::new(), + Handler::main(), + ); $this->assertInstanceOf(Signals::class, $process->signals()); $this->assertSame($process->signals(), $process->signals()); } + public function testAsyncSignals(): BlackBox\Proof + { + return $this + ->forAll(Set::of(...Signal::cases())) + ->prove(function($signal) { + $config = Config::new(); + $interceptor = Interceptor::new(); + $config = $config->handleSignalsVia( + $config->signalsHandler()->async($interceptor), + ); + $async = OperatingSystem::new($config); + $called = 0; + $async + ->process() + ->signals() + ->listen($signal, static function() use (&$called) { + ++$called; + }); + $interceptor->dispatch($signal); + + $this->assertSame(1, $called); + }); + } + public function testMemory() { - $process = CurrentProcess::of(Halt\Usleep::new()); + $process = CurrentProcess::of( + Halt\Usleep::new(), + Handler::main(), + ); $this->assertInstanceOf(Bytes::class, $process->memory()); $this->assertGreaterThan(3_000_000, $process->memory()->toInt()); // ~3MB