From ff3abb11776e727f0f3c464a1c31ede9613117e9 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 16:52:11 +0200 Subject: [PATCH 01/17] remove deprecated code --- CHANGELOG.md | 10 +++ src/CurrentProcess.php | 25 +----- src/CurrentProcess/Child.php | 56 ------------- src/CurrentProcess/Children.php | 67 --------------- src/CurrentProcess/ForkFailed.php | 12 --- src/CurrentProcess/Generic.php | 64 +------------- src/CurrentProcess/Logger.php | 33 -------- tests/CurrentProcess/ChildTest.php | 116 -------------------------- tests/CurrentProcess/ChildrenTest.php | 73 ---------------- tests/CurrentProcess/GenericTest.php | 82 ------------------ tests/CurrentProcess/LoggerTest.php | 78 ----------------- 11 files changed, 12 insertions(+), 604 deletions(-) delete mode 100644 src/CurrentProcess/Child.php delete mode 100644 src/CurrentProcess/Children.php delete mode 100644 src/CurrentProcess/ForkFailed.php delete mode 100644 tests/CurrentProcess/ChildTest.php delete mode 100644 tests/CurrentProcess/ChildrenTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 5197606..5bcf4de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [Unreleased] + +### Removed + +- `Innmind\OperatingSystem\CurrentProcess::fork()` +- `Innmind\OperatingSystem\CurrentProcess::children()` +- `Innmind\OperatingSystem\CurrentProcess\Children` +- `Innmind\OperatingSystem\CurrentProcess\Child` +- `Innmind\OperatingSystem\CurrentProcess\ForkFailed` + ## 3.8.0 - 2023-09-10 ### Deprecated diff --git a/src/CurrentProcess.php b/src/CurrentProcess.php index 1c8fbed..e86b64e 100644 --- a/src/CurrentProcess.php +++ b/src/CurrentProcess.php @@ -3,37 +3,14 @@ namespace Innmind\OperatingSystem; -use Innmind\OperatingSystem\CurrentProcess\{ - Children, - Child, - Signals, - ForkFailed, -}; +use Innmind\OperatingSystem\CurrentProcess\Signals; use Innmind\Server\Control\Server\Process\Pid; use Innmind\Server\Status\Server\Memory\Bytes; use Innmind\TimeContinuum\Period; -use Innmind\Immutable\{ - Either, - SideEffect, -}; interface CurrentProcess { public function id(): Pid; - - /** - * @deprecated This method will be removed in the next major version - * @psalm-suppress DeprecatedClass - * - * @return Either SideEffect represent the child side - */ - public function fork(): Either; - - /** - * @deprecated This method will be removed in the next major version - * @psalm-suppress DeprecatedClass - */ - public function children(): Children; public function signals(): Signals; public function halt(Period $period): void; public function memory(): Bytes; diff --git a/src/CurrentProcess/Child.php b/src/CurrentProcess/Child.php deleted file mode 100644 index 4f768c5..0000000 --- a/src/CurrentProcess/Child.php +++ /dev/null @@ -1,56 +0,0 @@ -pid = $pid; - } - - public static function of(Pid $pid): self - { - return new self($pid); - } - - public function id(): Pid - { - return $this->pid; - } - - public function running(): bool - { - return \is_int(\posix_getpgid($this->pid->toInt())); - } - - public function wait(): ExitCode - { - \pcntl_waitpid($this->pid->toInt(), $status); - /** @var int<0, 255> */ - $exitCode = \pcntl_wexitstatus($status); - - return new ExitCode($exitCode); - } - - public function kill(): void - { - \posix_kill($this->pid->toInt(), \SIGKILL); - } - - public function terminate(): void - { - \posix_kill($this->pid->toInt(), \SIGTERM); - } -} diff --git a/src/CurrentProcess/Children.php b/src/CurrentProcess/Children.php deleted file mode 100644 index 7806254..0000000 --- a/src/CurrentProcess/Children.php +++ /dev/null @@ -1,67 +0,0 @@ -, Child> */ - private Map $children; - - /** - * @no-named-arguments - */ - private function __construct(Child ...$children) - { - $this->children = Map::of( - ...Sequence::of(...$children) - ->map(static fn($child) => [$child->id()->toInt(), $child]) - ->toList(), - ); - } - - /** - * @no-named-arguments - */ - public static function of(Child ...$children): self - { - return new self(...$children); - } - - public function contains(Pid $pid): bool - { - return $this->children->contains($pid->toInt()); - } - - /** - * @return Maybe - */ - public function get(Pid $pid): Maybe - { - return $this->children->get($pid->toInt()); - } - - /** - * @return Map - */ - public function wait(): Map - { - return $this->children->flatMap( - static fn($_, $child) => Map::of([$child->id(), $child->wait()]), - ); - } -} diff --git a/src/CurrentProcess/ForkFailed.php b/src/CurrentProcess/ForkFailed.php deleted file mode 100644 index 41331ac..0000000 --- a/src/CurrentProcess/ForkFailed.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ - private Set $children; - private ?Handler $signalsHandler = null; private ?Signals\Wrapper $signals = null; private function __construct(Halt $halt) { $this->halt = $halt; - /** - * @psalm-suppress DeprecatedClass - * @var Set - */ - $this->children = Set::of(); } public static function of(Halt $halt): self @@ -47,50 +36,9 @@ public function id(): Pid return new Pid(\getmypid()); } - public function fork(): Either - { - /** - * @psalm-suppress ArgumentTypeCoercion - * @psalm-suppress DeprecatedClass - * @var Either - */ - $result = match ($pid = \pcntl_fork()) { - -1 => Either::left(new ForkFailed), - 0 => Either::right(new SideEffect), - default => Either::left(Child::of(new Pid($pid))), - }; - - /** - * @psalm-suppress DeprecatedClass - */ - return $result - ->map(function($sideEffect) { - $this->children = $this->children->clear(); - $this->signals = null; - $this->signalsHandler = $this->signalsHandler ? $this->signalsHandler->reset() : null; - - return $sideEffect; - }) - ->leftMap(fn($left) => match (true) { - $left instanceof Child => $this->register($left), - default => $left, - }); - } - - /** - * @psalm-suppress DeprecatedClass - */ - public function children(): Children - { - /** @psalm-suppress DeprecatedClass */ - return Children::of(...$this->children->toList()); - } - public function signals(): Signals { - return $this->signals ??= Signals\Wrapper::of( - $this->signalsHandler = new Handler, - ); + return $this->signals ??= Signals\Wrapper::of(new Handler); } public function halt(Period $period): void @@ -102,14 +50,4 @@ public function memory(): Bytes { return new Bytes(\memory_get_usage()); } - - /** - * @psalm-suppress DeprecatedClass - */ - private function register(Child $child): Child - { - $this->children = ($this->children)($child); - - return $child; - } } diff --git a/src/CurrentProcess/Logger.php b/src/CurrentProcess/Logger.php index 9ffc0b8..d5a597e 100644 --- a/src/CurrentProcess/Logger.php +++ b/src/CurrentProcess/Logger.php @@ -7,7 +7,6 @@ use Innmind\Server\Control\Server\Process\Pid; use Innmind\Server\Status\Server\Memory\Bytes; use Innmind\TimeContinuum\Period; -use Innmind\Immutable\Either; use Psr\Log\LoggerInterface; final class Logger implements CurrentProcess @@ -39,38 +38,6 @@ public function id(): Pid return $pid; } - public function fork(): Either - { - $this->logger->debug('Forking process'); - - /** - * @psalm-suppress DeprecatedMethod - * @psalm-suppress DeprecatedClass - */ - return $this - ->process - ->fork() - ->map(function($sideEffect) { - // @see Generic::fork() - // the child process reset the signal handlers to avoid side effects - // between parent and child so here we can safely reset the signals - // to free memory as listeners are kept in memory to reference the - // decorated listeners given to the underlying signals handler - $this->signals = null; - - return $sideEffect; - }); - } - - /** - * @psalm-suppress DeprecatedClass - */ - public function children(): Children - { - /** @psalm-suppress DeprecatedMethod */ - return $this->process->children(); - } - public function signals(): Signals { return $this->signals ??= Signals\Logger::psr( diff --git a/tests/CurrentProcess/ChildTest.php b/tests/CurrentProcess/ChildTest.php deleted file mode 100644 index 31097de..0000000 --- a/tests/CurrentProcess/ChildTest.php +++ /dev/null @@ -1,116 +0,0 @@ -assertSame($pid, $child->id()); - } - - public function testRunning() - { - $process = Generic::of($this->createMock(Halt::class)); - - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - \usleep(5000); - - exit(0); - } - - $this->assertInstanceOf(Child::class, $child); - $this->assertTrue($child->running()); - \sleep(1); - $child->wait(); - $this->assertFalse($child->running()); - } - - public function testWait() - { - $process = Generic::of($this->createMock(Halt::class)); - - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - \usleep(5000); - - exit(42); - } - - $this->assertInstanceOf(Child::class, $child); - $this->assertTrue($child->running()); - $exitCode = $child->wait(); - $this->assertInstanceOf(ExitCode::class, $exitCode); - $this->assertSame(42, $exitCode->toInt()); - $this->assertFalse($child->running()); - } - - public function testKill() - { - $process = Generic::of($this->createMock(Halt::class)); - - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - \usleep(5000); - - exit(42); - } - - $this->assertInstanceOf(Child::class, $child); - $this->assertTrue($child->running()); - $this->assertNull($child->kill()); - $exitCode = $child->wait(); - $this->assertFalse($child->running()); - $this->assertSame(0, $exitCode->toInt()); - } - - public function testTerminate() - { - $process = Generic::of($this->createMock(Halt::class)); - - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - \usleep(5000); - - exit(42); - } - - $this->assertInstanceOf(Child::class, $child); - $this->assertTrue($child->running()); - $this->assertNull($child->terminate()); - $exitCode = $child->wait(); - $this->assertSame(0, $exitCode->toInt()); - $this->assertFalse($child->running()); - } -} diff --git a/tests/CurrentProcess/ChildrenTest.php b/tests/CurrentProcess/ChildrenTest.php deleted file mode 100644 index 81459af..0000000 --- a/tests/CurrentProcess/ChildrenTest.php +++ /dev/null @@ -1,73 +0,0 @@ -assertTrue($children->contains(new Pid(10))); - $this->assertTrue($children->contains(new Pid(20))); - $this->assertFalse($children->contains(new Pid(30))); - $this->assertSame($child1, $children->get(new Pid(10))->match( - static fn($child) => $child, - static fn() => null, - )); - $this->assertSame($child2, $children->get(new Pid(20))->match( - static fn($child) => $child, - static fn() => null, - )); - } - - public function testWait() - { - $process = Generic::of($this->createMock(Halt::class)); - - $start = \microtime(true); - $children = []; - $count = 0; - - foreach (\range(2, 3) as $i) { - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - \sleep($i); - - exit(0); - } - - $this->assertInstanceOf(Child::class, $child); - $children[] = $child; - ++$count; - } - - $children = Children::of(...$children); - - $codes = $children->wait(); - $this->assertCount($count, $codes); - $codes->foreach(function($pid, $code) use ($children) { - $this->assertTrue($children->contains($pid)); - $this->assertSame(0, $code->toInt()); - }); - $delta = \microtime(true) - $start; - $this->assertEqualsWithDelta(3, $delta, 0.2); - } -} diff --git a/tests/CurrentProcess/GenericTest.php b/tests/CurrentProcess/GenericTest.php index 33649fb..668a17a 100644 --- a/tests/CurrentProcess/GenericTest.php +++ b/tests/CurrentProcess/GenericTest.php @@ -5,8 +5,6 @@ use Innmind\OperatingSystem\{ CurrentProcess\Generic, - CurrentProcess\Children, - CurrentProcess\Child, CurrentProcess\Signals, CurrentProcess, }; @@ -14,7 +12,6 @@ use Innmind\Server\Status\Server\Memory\Bytes; use Innmind\TimeContinuum\Period; use Innmind\TimeWarp\Halt; -use Innmind\Signals\Signal; use PHPUnit\Framework\TestCase; class GenericTest extends TestCase @@ -35,49 +32,6 @@ public function testId() $this->assertSame($process->id()->toInt(), $process->id()->toInt()); } - public function testFork() - { - $process = Generic::of($this->createMock(Halt::class)); - - $parentId = $process->id()->toInt(); - - $result = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($result)) { - // child cannot be tested as it can't reference the current output - // (otherwise it will result in a weird output) - exit(0); - } - - $this->assertInstanceOf(Child::class, $result); - $this->assertSame($parentId, $process->id()->toInt()); - $this->assertNotSame($parentId, $result->id()->toInt()); - } - - public function testChildren() - { - $process = Generic::of($this->createMock(Halt::class)); - - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - $code = $process->children()->contains($process->id()) ? 1 : 0; - - exit($code); - } - - $this->assertInstanceOf(Children::class, $process->children()); - $this->assertInstanceOf(Child::class, $child); - $this->assertTrue($process->children()->contains($child->id())); - $this->assertSame(0, $child->wait()->toInt()); - } - public function testHalt() { $process = Generic::of( @@ -100,42 +54,6 @@ public function testSignals() $this->assertSame($process->signals(), $process->signals()); } - public function testSignalsAreResettedInForkChild() - { - $process = Generic::of($this->createMock(Halt::class)); - $signals = $process->signals(); - $signals->listen(Signal::terminate, static function(...$args) { - exit(1); - }); - - $child = $process->fork()->match( - static fn() => null, - static fn($left) => $left, - ); - - if (\is_null($child)) { - if ($process->signals() === $signals) { - exit(2); - } - - \sleep(2); - - exit(0); - } - - // for some reason if we don't wait the signal handlers are still active - // in the child process, the current guess is that without this sleep the - // terminate all below is done before the child is correctly initialized - // and had the chance to reset the signal handler - // the intriguing thing is that instead of a sleep we do a (symfony) - // dump(true) it have the time to remove the child signal handler - \sleep(1); - - $this->assertInstanceOf(Child::class, $child); - $child->terminate(); // should not trigger the listener in the child - $this->assertSame(0, $child->wait()->toInt()); - } - public function testMemory() { $process = Generic::of($this->createMock(Halt::class)); diff --git a/tests/CurrentProcess/LoggerTest.php b/tests/CurrentProcess/LoggerTest.php index c4d73c1..812fe6b 100644 --- a/tests/CurrentProcess/LoggerTest.php +++ b/tests/CurrentProcess/LoggerTest.php @@ -6,16 +6,11 @@ use Innmind\OperatingSystem\{ CurrentProcess\Logger, CurrentProcess\Signals, - CurrentProcess\Children, CurrentProcess, }; use Innmind\Server\Control\Server\Process\Pid; use Innmind\Server\Status\Server\Memory\Bytes; use Innmind\TimeContinuum\Period; -use Innmind\Immutable\{ - Either, - SideEffect, -}; use Psr\Log\LoggerInterface; use PHPUnit\Framework\TestCase; use Innmind\BlackBox\{ @@ -72,79 +67,6 @@ public function testAlwaysUseSameSignalInstance() $this->assertSame($process->signals(), $process->signals()); } - public function testFork() - { - $this - ->forAll(new Set\Either( - Set\Elements::of(Either::right(new SideEffect)), - Set\Decorate::immutable( - static fn($id) => Either::left(new Pid($id)), - Set\Integers::above(2), - ), - )) - ->then(function($expected) { - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('fork') - ->willReturn($expected); - $logger = $this->createMock(LoggerInterface::class); - $logger - ->expects($this->once()) - ->method('debug') - ->with('Forking process'); - $process = Logger::psr($inner, $logger); - - $this->assertEquals($expected, $process->fork()); - }); - } - - public function testSignalsInstanceIsResettedInTheChildProcessWhenForking() - { - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('fork') - ->willReturn(Either::right(new SideEffect)); - $logger = $this->createMock(LoggerInterface::class); - $process = Logger::psr($inner, $logger); - $original = $process->signals(); - $process->fork(); - - $this->assertNotSame($original, $process->signals()); - } - - public function testSignalsInstanceIsKeptInTheParentProcessWhenForking() - { - $this - ->forAll(Set\Integers::above(2)) - ->then(function($child) { - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('fork') - ->willReturn(Either::left(new Pid($child))); - $logger = $this->createMock(LoggerInterface::class); - $process = Logger::psr($inner, $logger); - $original = $process->signals(); - $process->fork(); - - $this->assertSame($original, $process->signals()); - }); - } - - public function testChildren() - { - $inner = $this->createMock(CurrentProcess::class); - $inner - ->expects($this->once()) - ->method('children') - ->willReturn($expected = Children::of()); - $process = Logger::psr($inner, $this->createMock(LoggerInterface::class)); - - $this->assertSame($expected, $process->children()); - } - public function testHalt() { $period = $this->createMock(Period::class); From 5c34d7ee75117a66d49100a898efff436314f5b9 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 16:55:31 +0200 Subject: [PATCH 02/17] use psalm 5 --- composer.json | 2 +- psalm.xml | 2 ++ src/Filesystem/Generic.php | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d3efe34..6d38181 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "phpunit/phpunit": "~9.0", "innmind/url": "~4.0", "innmind/ip": "~3.0", - "vimeo/psalm": "~4.30", + "vimeo/psalm": "~5.15", "innmind/black-box": "^4.8", "innmind/coding-standard": "~2.0" } diff --git a/psalm.xml b/psalm.xml index 3240886..bd44196 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,8 @@ mounted as $adapter => $mounted) { if ($path->toString() === $mounted) { return $adapter; From 8f4c63829737f120cc0f31aa76b7ddd40d5ddc12 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:00:14 +0200 Subject: [PATCH 03/17] use blackbox 5 --- .gitignore | 1 + composer.json | 4 +-- phpunit.xml.dist | 21 ++++++++------ tests/CurrentProcess/Signals/LoggerTest.php | 32 ++++++++++++--------- tests/Filesystem/LoggerTest.php | 2 +- 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index e96516b..7330583 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock vendor .phpunit.result.cache +.phpunit.cache diff --git a/composer.json b/composer.json index 6d38181..09bbcb8 100644 --- a/composer.json +++ b/composer.json @@ -39,11 +39,11 @@ } }, "require-dev": { - "phpunit/phpunit": "~9.0", + "phpunit/phpunit": "~10.2", "innmind/url": "~4.0", "innmind/ip": "~3.0", "vimeo/psalm": "~5.15", - "innmind/black-box": "^4.8", + "innmind/black-box": "~5.5", "innmind/coding-standard": "~2.0" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 51d31c5..3c2816b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,16 @@ - - + + + + + + + + + ./tests + + + . @@ -8,10 +18,5 @@ ./tests ./vendor - - - - ./tests - - + diff --git a/tests/CurrentProcess/Signals/LoggerTest.php b/tests/CurrentProcess/Signals/LoggerTest.php index 6efdb55..f8fa3b5 100644 --- a/tests/CurrentProcess/Signals/LoggerTest.php +++ b/tests/CurrentProcess/Signals/LoggerTest.php @@ -81,15 +81,17 @@ public function testLogWhenListenerCalled() })); $logger = $this->createMock(LoggerInterface::class); $logger - ->expects($this->exactly(2)) + ->expects($matcher = $this->exactly(2)) ->method('debug') - ->withConsecutive( - [], - [ - 'Handling signal {signal}', - ['signal' => $signal->toInt()], - ], - ); + ->willReturnCallback(function($message, $context) use ($matcher, $signal) { + if ($matcher->numberOfInvocations() === 2) { + $this->assertSame('Handling signal {signal}', $message); + $this->assertSame( + ['signal' => $signal->toInt()], + $context, + ); + } + }); $signals = Logger::psr($inner, $logger); $called = false; @@ -126,12 +128,16 @@ public function testUseSameRegisteredListenerWhenRemovingOne() })); $logger = $this->createMock(LoggerInterface::class); $logger - ->expects($this->exactly(2)) + ->expects($matcher = $this->exactly(2)) ->method('debug') - ->withConsecutive( - [], - ['Removing a signal listener'], - ); + ->willReturnCallback(function($message) use ($matcher) { + if ($matcher->numberOfInvocations() === 2) { + $this->assertSame( + 'Removing a signal listener', + $message, + ); + } + }); $signals = Logger::psr($inner, $logger); $listener = static fn() => null; diff --git a/tests/Filesystem/LoggerTest.php b/tests/Filesystem/LoggerTest.php index ef62346..b4dde20 100644 --- a/tests/Filesystem/LoggerTest.php +++ b/tests/Filesystem/LoggerTest.php @@ -143,7 +143,7 @@ public function testLogRequiredFile() $this ->forAll( Path::any(), - Set\AnyType::any(), + Set\Type::any(), ) ->then(function($path, $value) { $inner = $this->createMock(Filesystem::class); From 5b7219713373a0c04b6c3f56e4836e1b716a4b5e Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:01:38 +0200 Subject: [PATCH 04/17] drop php 8.1 support --- .github/workflows/ci.yml | 6 +++--- CHANGELOG.md | 1 + composer.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70b6c31..50158ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest] - php-version: ['8.1', '8.2'] + php-version: ['8.2'] dependencies: ['lowest', 'highest'] name: 'PHPUnit' steps: @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['8.1', '8.2'] + php-version: ['8.2'] dependencies: ['lowest', 'highest'] name: 'Psalm' steps: @@ -54,7 +54,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['8.1'] + php-version: ['8.2'] name: 'CS' steps: - name: Checkout diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bcf4de..a41c10e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - `Innmind\OperatingSystem\CurrentProcess\Children` - `Innmind\OperatingSystem\CurrentProcess\Child` - `Innmind\OperatingSystem\CurrentProcess\ForkFailed` +- Support for PHP `8.1` ## 3.8.0 - 2023-09-10 diff --git a/composer.json b/composer.json index 09bbcb8..5268dda 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "issues": "http://github.com/Innmind/OperatingSystem/issues" }, "require": { - "php": "~8.1", + "php": "~8.2", "innmind/time-continuum": "~3.0", "innmind/server-status": "~4.0", "innmind/server-control": "~5.0", From 55478640c625166b050e3abf0d70424ef0c769dd Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:02:07 +0200 Subject: [PATCH 05/17] test against php 8.3 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50158ba..a5f5976 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest] - php-version: ['8.2'] + php-version: ['8.2', '8.3'] dependencies: ['lowest', 'highest'] name: 'PHPUnit' steps: @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['8.2'] + php-version: ['8.2', '8.3'] dependencies: ['lowest', 'highest'] name: 'Psalm' steps: From 03f495a8a62bd93900845b2f95a9d1f3aabffa9b Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:06:38 +0200 Subject: [PATCH 06/17] use http and filesystem 7 --- composer.json | 4 ++-- src/Remote/Generic.php | 2 -- tests/FactoryTest.php | 8 ++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 5268dda..792377d 100644 --- a/composer.json +++ b/composer.json @@ -19,9 +19,9 @@ "innmind/time-continuum": "~3.0", "innmind/server-status": "~4.0", "innmind/server-control": "~5.0", - "innmind/filesystem": "~6.2", + "innmind/filesystem": "~7.1", "innmind/socket": "~6.0", - "innmind/http-transport": "~6.4", + "innmind/http-transport": "~7.0", "innmind/time-warp": "~3.0", "innmind/signals": "~3.0", "innmind/file-watch": "~3.1", diff --git a/src/Remote/Generic.php b/src/Remote/Generic.php index 82d0dc9..b77fe54 100644 --- a/src/Remote/Generic.php +++ b/src/Remote/Generic.php @@ -11,7 +11,6 @@ Server, Servers, }; -use Innmind\Filesystem\Chunk; use Innmind\TimeContinuum\Clock; use Innmind\Socket\{ Internet\Transport, @@ -81,7 +80,6 @@ public function http(): HttpTransport $http = Curl::of( $this->clock, - new Chunk, $this->config->streamCapabilities(), ); diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index 0fd9520..938e203 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -13,9 +13,9 @@ Earth, }; use Innmind\Filesystem\{ - File\File, + File, File\Content, - Directory\Directory, + Directory, }; use Innmind\Url\Path; use Symfony\Component\Filesystem\Filesystem as FS; @@ -55,9 +55,9 @@ public function testPersistingFileOnCaseInsensitiveFilesystem() ->mount(Path::of($path)); $adapter->add( $directory = Directory::named('0') - ->add($file = File::named('L', Content\None::of())) + ->add($file = File::named('L', Content::none())) ->remove($file->name()) - ->add($file = File::named('l', Content\None::of())) + ->add($file = File::named('l', Content::none())) ->remove($file->name()) ->add($file), ); From d06550602ca0a892598bb7e68df802215d8311d1 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:07:15 +0200 Subject: [PATCH 07/17] remove OS\Unix::config() --- src/OperatingSystem/Unix.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/OperatingSystem/Unix.php b/src/OperatingSystem/Unix.php index 45f7ee5..01ae987 100644 --- a/src/OperatingSystem/Unix.php +++ b/src/OperatingSystem/Unix.php @@ -46,14 +46,6 @@ public static function of(Clock $clock, Config $config = null): self return new self($clock, $config ?? Config::of()); } - /** - * @internal - */ - public function config(): Config - { - return $this->config; - } - public function clock(): Clock { return $this->clock; From 11a6040d05108132e4724a8c978ecee3199e8606 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:15:21 +0200 Subject: [PATCH 08/17] simplify the factory arguments --- CHANGELOG.md | 4 ++++ src/Config.php | 34 ++++++++++++++++++++++++++++++ src/Factory.php | 8 +++---- src/OperatingSystem/Unix.php | 12 +++++------ tests/FactoryTest.php | 4 ++-- tests/OperatingSystem/UnixTest.php | 3 ++- 6 files changed, 50 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a41c10e..3f94e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Changed + +- `Innmind\OperatingSystem\Factory::build()` now only accept a `Config` object, use `Config::withClock()` to change the default clock + ### Removed - `Innmind\OperatingSystem\CurrentProcess::fork()` diff --git a/src/Config.php b/src/Config.php index 230151d..2659129 100644 --- a/src/Config.php +++ b/src/Config.php @@ -3,6 +3,10 @@ namespace Innmind\OperatingSystem; +use Innmind\TimeContinuum\{ + Clock, + Earth, +}; use Innmind\Filesystem\CaseSensitivity; use Innmind\Server\Status\EnvironmentPath; use Innmind\Stream\{ @@ -13,6 +17,7 @@ final class Config { + private Clock $clock; private CaseSensitivity $caseSensitivity; private Capabilities $streamCapabilities; private EnvironmentPath $path; @@ -23,11 +28,13 @@ final class Config * @param Maybe $maxHttpConcurrency */ private function __construct( + Clock $clock, CaseSensitivity $caseSensitivity, Capabilities $streamCapabilities, EnvironmentPath $path, Maybe $maxHttpConcurrency, ) { + $this->clock = $clock; $this->caseSensitivity = $caseSensitivity; $this->streamCapabilities = $streamCapabilities; $this->path = $path; @@ -40,6 +47,7 @@ public static function of(): self $maxHttpConcurrency = Maybe::nothing(); return new self( + new Earth\Clock, CaseSensitivity::sensitive, Streams::fromAmbientAuthority(), EnvironmentPath::of(\getenv('PATH') ?: ''), @@ -47,12 +55,27 @@ public static function of(): self ); } + /** + * @psalm-mutation-free + */ + public function withClock(Clock $clock): self + { + return new self( + $clock, + $this->caseSensitivity, + $this->streamCapabilities, + $this->path, + $this->maxHttpConcurrency, + ); + } + /** * @psalm-mutation-free */ public function caseInsensitiveFilesystem(): self { return new self( + $this->clock, CaseSensitivity::insensitive, $this->streamCapabilities, $this->path, @@ -66,6 +89,7 @@ public function caseInsensitiveFilesystem(): self public function useStreamCapabilities(Capabilities $capabilities): self { return new self( + $this->clock, $this->caseSensitivity, $capabilities, $this->path, @@ -79,6 +103,7 @@ public function useStreamCapabilities(Capabilities $capabilities): self public function withEnvironmentPath(EnvironmentPath $path): self { return new self( + $this->clock, $this->caseSensitivity, $this->streamCapabilities, $path, @@ -94,6 +119,7 @@ public function withEnvironmentPath(EnvironmentPath $path): self public function limitHttpConcurrencyTo(int $max): self { return new self( + $this->clock, $this->caseSensitivity, $this->streamCapabilities, $this->path, @@ -101,6 +127,14 @@ public function limitHttpConcurrencyTo(int $max): self ); } + /** + * @internal + */ + public function clock(): Clock + { + return $this->clock; + } + /** * @internal */ diff --git a/src/Factory.php b/src/Factory.php index 5410346..2fa92cd 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -10,14 +10,12 @@ final class Factory { - public static function build( - Clock $clock = null, - Config $config = null, - ): OperatingSystem { + public static function build(Config $config = null): OperatingSystem + { switch (\PHP_OS) { case 'Darwin': case 'Linux': - return OperatingSystem\Unix::of($clock ?? new Earth\Clock, $config); + return OperatingSystem\Unix::of($config); } throw new \LogicException('Unuspported operating system'); diff --git a/src/OperatingSystem/Unix.php b/src/OperatingSystem/Unix.php index 01ae987..54c3717 100644 --- a/src/OperatingSystem/Unix.php +++ b/src/OperatingSystem/Unix.php @@ -25,7 +25,6 @@ final class Unix implements OperatingSystem { - private Clock $clock; private Config $config; private ?Filesystem $filesystem = null; private ?ServerStatus $status = null; @@ -35,20 +34,19 @@ final class Unix implements OperatingSystem private ?Remote $remote = null; private ?CurrentProcess $process = null; - private function __construct(Clock $clock, Config $config) + private function __construct(Config $config) { - $this->clock = $clock; $this->config = $config; } - public static function of(Clock $clock, Config $config = null): self + public static function of(Config $config = null): self { - return new self($clock, $config ?? Config::of()); + return new self($config ?? Config::of()); } public function clock(): Clock { - return $this->clock; + return $this->config->clock(); } public function filesystem(): Filesystem @@ -56,7 +54,7 @@ public function filesystem(): Filesystem return $this->filesystem ??= Filesystem\Generic::of( $this->control()->processes(), new Usleep, - $this->clock, + $this->clock(), $this->config, ); } diff --git a/tests/FactoryTest.php b/tests/FactoryTest.php index 938e203..ec5d0d2 100644 --- a/tests/FactoryTest.php +++ b/tests/FactoryTest.php @@ -27,7 +27,7 @@ public function testBuild() { $clock = $this->createMock(Clock::class); - $os = Factory::build($clock); + $os = Factory::build(Config::of()->withClock($clock)); $this->assertInstanceOf(Unix::class, $os); $this->assertSame($clock, $os->clock()); @@ -49,7 +49,7 @@ public function testPersistingFileOnCaseInsensitiveFilesystem() $path = \sys_get_temp_dir().'/innmind/filesystem/'; (new FS)->remove($path); - $os = Factory::build(null, Config::of()->caseInsensitiveFilesystem()); + $os = Factory::build(Config::of()->caseInsensitiveFilesystem()); $adapter = $os ->filesystem() ->mount(Path::of($path)); diff --git a/tests/OperatingSystem/UnixTest.php b/tests/OperatingSystem/UnixTest.php index a1358fc..2596b38 100644 --- a/tests/OperatingSystem/UnixTest.php +++ b/tests/OperatingSystem/UnixTest.php @@ -11,6 +11,7 @@ Sockets, Remote, CurrentProcess, + Config, }; use Innmind\Server\Status\Server as ServerStatus; use Innmind\Server\Control\Server as ServerControl; @@ -23,7 +24,7 @@ public function testInterface() { $clock = $this->createMock(Clock::class); - $os = Unix::of($clock); + $os = Unix::of(Config::of()->withClock($clock)); $this->assertInstanceOf(OperatingSystem::class, $os); $this->assertSame($clock, $os->clock()); From 1d13aabb3450c8693c44ebab6f7734a9cad08efb Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:21:02 +0200 Subject: [PATCH 09/17] force injecting the Config --- src/Filesystem/Generic.php | 4 ++-- src/Remote/Generic.php | 4 ++-- src/Sockets/Unix.php | 4 ++-- tests/Filesystem/GenericTest.php | 9 +++++++++ tests/Remote/GenericTest.php | 7 +++++++ tests/Sockets/UnixTest.php | 11 ++++++----- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Filesystem/Generic.php b/src/Filesystem/Generic.php index 88d8747..2da3b81 100644 --- a/src/Filesystem/Generic.php +++ b/src/Filesystem/Generic.php @@ -44,9 +44,9 @@ public static function of( Processes $processes, Halt $halt, Clock $clock, - Config $config = null, + Config $config, ): self { - return new self($processes, $halt, $clock, $config ?? Config::of()); + return new self($processes, $halt, $clock, $config); } public function mount(Path $path): Adapter diff --git a/src/Remote/Generic.php b/src/Remote/Generic.php index b77fe54..5b5ac85 100644 --- a/src/Remote/Generic.php +++ b/src/Remote/Generic.php @@ -45,9 +45,9 @@ private function __construct(Server $server, Clock $clock, Config $config) public static function of( Server $server, Clock $clock, - Config $config = null, + Config $config, ): self { - return new self($server, $clock, $config ?? Config::of()); + return new self($server, $clock, $config); } public function ssh(Url $server): Server diff --git a/src/Sockets/Unix.php b/src/Sockets/Unix.php index 1b08a77..85a3210 100644 --- a/src/Sockets/Unix.php +++ b/src/Sockets/Unix.php @@ -25,9 +25,9 @@ private function __construct(Config $config) $this->config = $config; } - public static function of(Config $config = null): self + public static function of(Config $config): self { - return new self($config ?? Config::of()); + return new self($config); } public function open(Address $address): Maybe diff --git a/tests/Filesystem/GenericTest.php b/tests/Filesystem/GenericTest.php index 0d8ccf1..92397a2 100644 --- a/tests/Filesystem/GenericTest.php +++ b/tests/Filesystem/GenericTest.php @@ -6,6 +6,7 @@ use Innmind\OperatingSystem\{ Filesystem\Generic, Filesystem, + Config, }; use Innmind\Filesystem\Adapter\Filesystem as FilesystemAdapter; use Innmind\Url\Path; @@ -29,6 +30,7 @@ public function testInterface() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ), ); } @@ -39,6 +41,7 @@ public function testMount() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $adapter = $filesystem->mount(Path::of('/tmp/')); @@ -52,6 +55,7 @@ public function testMountingTheSamePathTwiceReturnsTheSameAdapter() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $adapter = $filesystem->mount(Path::of('/tmp/')); @@ -65,6 +69,7 @@ public function testContainsFile() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $this->assertFalse($filesystem->contains(Path::of('/tmp/foo'))); @@ -79,6 +84,7 @@ public function testContainsDirectory() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $this->assertFalse($filesystem->contains(Path::of('/tmp/some-dir/'))); @@ -93,6 +99,7 @@ public function testWatch() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $this->assertInstanceOf(Ping::class, $filesystem->watch(Path::of('/somewhere'))); @@ -107,6 +114,7 @@ public function testRequireUnknownFile() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $this->assertFalse($filesystem->require($path)->match( @@ -122,6 +130,7 @@ public function testRequireFile() $this->createMock(Processes::class), $this->createMock(Halt::class), $this->createMock(Clock::class), + Config::of(), ); $this->assertSame(42, $filesystem->require(Path::of(__DIR__.'/fixture.php'))->match( diff --git a/tests/Remote/GenericTest.php b/tests/Remote/GenericTest.php index cb721f2..c026f60 100644 --- a/tests/Remote/GenericTest.php +++ b/tests/Remote/GenericTest.php @@ -6,6 +6,7 @@ use Innmind\OperatingSystem\{ Remote\Generic, Remote, + Config, }; use Innmind\Server\Control\{ Server, @@ -40,6 +41,7 @@ public function testInterface() Generic::of( $this->createMock(Server::class), $this->createMock(Clock::class), + Config::of(), ), ); } @@ -49,6 +51,7 @@ public function testSsh() $remote = Generic::of( $server = $this->createMock(Server::class), $this->createMock(Clock::class), + Config::of(), ); $server ->expects($this->once()) @@ -72,6 +75,7 @@ public function testSshWithoutPort() $remote = Generic::of( $server = $this->createMock(Server::class), $this->createMock(Clock::class), + Config::of(), ); $server ->expects($this->once()) @@ -95,6 +99,7 @@ public function testSocket() $remote = Generic::of( $this->createMock(Server::class), $this->createMock(Clock::class), + Config::of(), ); $server = InternetServer::of(Transport::tcp(), IPv4::localhost(), Port::of(1234))->match( static fn($server) => $server, @@ -116,6 +121,7 @@ public function testHttp() $remote = Generic::of( $this->createMock(Server::class), $this->createMock(Clock::class), + Config::of(), ); $http = $remote->http(); @@ -132,6 +138,7 @@ public function testSql() $remote = Generic::of( $this->createMock(Server::class), $this->createMock(Clock::class), + Config::of(), ); $sql = $remote->sql($server); diff --git a/tests/Sockets/UnixTest.php b/tests/Sockets/UnixTest.php index e697654..069f8dc 100644 --- a/tests/Sockets/UnixTest.php +++ b/tests/Sockets/UnixTest.php @@ -6,6 +6,7 @@ use Innmind\OperatingSystem\{ Sockets\Unix, Sockets, + Config, }; use Innmind\Socket\{ Address\Unix as Address, @@ -20,12 +21,12 @@ class UnixTest extends TestCase { public function testInterface() { - $this->assertInstanceOf(Sockets::class, Unix::of()); + $this->assertInstanceOf(Sockets::class, Unix::of(Config::of())); } public function testOpen() { - $sockets = Unix::of(); + $sockets = Unix::of(Config::of()); $socket = $sockets->open(Address::of('/tmp/foo'))->match( static fn($server) => $server, @@ -44,7 +45,7 @@ public function testOpen() public function testTakeOver() { - $sockets = Unix::of(); + $sockets = Unix::of(Config::of()); $socket = $sockets->open(Address::of('/tmp/foo'))->match( static fn($server) => $server, @@ -62,7 +63,7 @@ public function testTakeOver() public function testConnectTo() { - $sockets = Unix::of(); + $sockets = Unix::of(Config::of()); $server = $sockets->open(Address::of('/tmp/foo'))->match( static fn($server) => $server, @@ -80,7 +81,7 @@ public function testConnectTo() public function testWatch() { - $sockets = Unix::of(); + $sockets = Unix::of(Config::of()); $this->assertInstanceOf( Watch::class, From cb8e4bae73b7e1a8d9ad3a5042fd4d06268d6c85 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:23:33 +0200 Subject: [PATCH 10/17] remove unused dependency --- src/Filesystem/Generic.php | 7 +------ src/OperatingSystem/Unix.php | 1 - tests/Filesystem/GenericTest.php | 9 --------- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/Filesystem/Generic.php b/src/Filesystem/Generic.php index 2da3b81..6b55ec6 100644 --- a/src/Filesystem/Generic.php +++ b/src/Filesystem/Generic.php @@ -11,7 +11,6 @@ use Innmind\Url\Path; use Innmind\Server\Control\Server\Processes; use Innmind\TimeWarp\Halt; -use Innmind\TimeContinuum\Clock; use Innmind\FileWatch\{ Ping, Factory, @@ -22,7 +21,6 @@ final class Generic implements Filesystem { private Watch $watch; - private Clock $clock; private Config $config; /** @var \WeakMap */ private \WeakMap $mounted; @@ -30,11 +28,9 @@ final class Generic implements Filesystem private function __construct( Processes $processes, Halt $halt, - Clock $clock, Config $config, ) { $this->watch = Factory::build($processes, $halt); - $this->clock = $clock; $this->config = $config; /** @var \WeakMap */ $this->mounted = new \WeakMap; @@ -43,10 +39,9 @@ private function __construct( public static function of( Processes $processes, Halt $halt, - Clock $clock, Config $config, ): self { - return new self($processes, $halt, $clock, $config); + return new self($processes, $halt, $config); } public function mount(Path $path): Adapter diff --git a/src/OperatingSystem/Unix.php b/src/OperatingSystem/Unix.php index 54c3717..f2cf627 100644 --- a/src/OperatingSystem/Unix.php +++ b/src/OperatingSystem/Unix.php @@ -54,7 +54,6 @@ public function filesystem(): Filesystem return $this->filesystem ??= Filesystem\Generic::of( $this->control()->processes(), new Usleep, - $this->clock(), $this->config, ); } diff --git a/tests/Filesystem/GenericTest.php b/tests/Filesystem/GenericTest.php index 92397a2..013b2f6 100644 --- a/tests/Filesystem/GenericTest.php +++ b/tests/Filesystem/GenericTest.php @@ -12,7 +12,6 @@ use Innmind\Url\Path; use Innmind\Server\Control\Server\Processes; use Innmind\TimeWarp\Halt; -use Innmind\TimeContinuum\Clock; use Innmind\FileWatch\Ping; use Fixtures\Innmind\Url\Path as FPath; use PHPUnit\Framework\TestCase; @@ -29,7 +28,6 @@ public function testInterface() Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ), ); @@ -40,7 +38,6 @@ public function testMount() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); @@ -54,7 +51,6 @@ public function testMountingTheSamePathTwiceReturnsTheSameAdapter() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); @@ -68,7 +64,6 @@ public function testContainsFile() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); @@ -83,7 +78,6 @@ public function testContainsDirectory() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); @@ -98,7 +92,6 @@ public function testWatch() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); @@ -113,7 +106,6 @@ public function testRequireUnknownFile() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); @@ -129,7 +121,6 @@ public function testRequireFile() $filesystem = Generic::of( $this->createMock(Processes::class), $this->createMock(Halt::class), - $this->createMock(Clock::class), Config::of(), ); From 8d5b288073e206cf561d5a73efc7ed0764b547e9 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:34:25 +0200 Subject: [PATCH 11/17] inject the IO abstraction everywhere possible --- composer.json | 3 ++- src/Config.php | 28 +++++++++++++++++++++++++++- src/Filesystem/Generic.php | 6 +++++- src/Remote/Generic.php | 1 + 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 792377d..494e623 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "innmind/signals": "~3.0", "innmind/file-watch": "~3.1", "innmind/stream": "~4.0", - "formal/access-layer": "^2.0" + "formal/access-layer": "^2.0", + "innmind/io": "~2.2" }, "autoload": { "psr-4": { diff --git a/src/Config.php b/src/Config.php index 2659129..a9c35de 100644 --- a/src/Config.php +++ b/src/Config.php @@ -6,9 +6,11 @@ use Innmind\TimeContinuum\{ Clock, Earth, + ElapsedPeriod, }; use Innmind\Filesystem\CaseSensitivity; use Innmind\Server\Status\EnvironmentPath; +use Innmind\IO\IO; use Innmind\Stream\{ Capabilities, Streams, @@ -20,6 +22,7 @@ final class Config private Clock $clock; private CaseSensitivity $caseSensitivity; private Capabilities $streamCapabilities; + private IO $io; private EnvironmentPath $path; /** @var Maybe */ private Maybe $maxHttpConcurrency; @@ -31,12 +34,14 @@ private function __construct( Clock $clock, CaseSensitivity $caseSensitivity, Capabilities $streamCapabilities, + IO $io, EnvironmentPath $path, Maybe $maxHttpConcurrency, ) { $this->clock = $clock; $this->caseSensitivity = $caseSensitivity; $this->streamCapabilities = $streamCapabilities; + $this->io = $io; $this->path = $path; $this->maxHttpConcurrency = $maxHttpConcurrency; } @@ -49,7 +54,11 @@ public static function of(): self return new self( new Earth\Clock, CaseSensitivity::sensitive, - Streams::fromAmbientAuthority(), + $streams = Streams::fromAmbientAuthority(), + IO::of(static fn(?ElapsedPeriod $timeout) => match ($timeout) { + null => $streams->watch()->waitForever(), + default => $streams->watch()->timeoutAfter($timeout), + }), EnvironmentPath::of(\getenv('PATH') ?: ''), $maxHttpConcurrency, ); @@ -64,6 +73,7 @@ public function withClock(Clock $clock): self $clock, $this->caseSensitivity, $this->streamCapabilities, + $this->io, $this->path, $this->maxHttpConcurrency, ); @@ -78,6 +88,7 @@ public function caseInsensitiveFilesystem(): self $this->clock, CaseSensitivity::insensitive, $this->streamCapabilities, + $this->io, $this->path, $this->maxHttpConcurrency, ); @@ -88,10 +99,15 @@ public function caseInsensitiveFilesystem(): self */ public function useStreamCapabilities(Capabilities $capabilities): self { + /** @psalm-suppress ImpureMethodCall This should be solved in the next innmind/io release */ return new self( $this->clock, $this->caseSensitivity, $capabilities, + IO::of(static fn(?ElapsedPeriod $timeout) => match ($timeout) { + null => $capabilities->watch()->waitForever(), + default => $capabilities->watch()->timeoutAfter($timeout), + }), $this->path, $this->maxHttpConcurrency, ); @@ -106,6 +122,7 @@ public function withEnvironmentPath(EnvironmentPath $path): self $this->clock, $this->caseSensitivity, $this->streamCapabilities, + $this->io, $path, $this->maxHttpConcurrency, ); @@ -122,6 +139,7 @@ public function limitHttpConcurrencyTo(int $max): self $this->clock, $this->caseSensitivity, $this->streamCapabilities, + $this->io, $this->path, Maybe::just($max), ); @@ -151,6 +169,14 @@ public function streamCapabilities(): Capabilities return $this->streamCapabilities; } + /** + * @internal + */ + public function io(): IO + { + return $this->io; + } + /** * @internal */ diff --git a/src/Filesystem/Generic.php b/src/Filesystem/Generic.php index 6b55ec6..bd60a62 100644 --- a/src/Filesystem/Generic.php +++ b/src/Filesystem/Generic.php @@ -56,7 +56,11 @@ public function mount(Path $path): Adapter } } - $adapter = Adapter\Filesystem::mount($path, $this->config->streamCapabilities()) + $adapter = Adapter\Filesystem::mount( + $path, + $this->config->streamCapabilities(), + $this->config->io(), + ) ->withCaseSensitivity( $this->config->filesystemCaseSensitivity(), ); diff --git a/src/Remote/Generic.php b/src/Remote/Generic.php index 5b5ac85..766d07e 100644 --- a/src/Remote/Generic.php +++ b/src/Remote/Generic.php @@ -81,6 +81,7 @@ public function http(): HttpTransport $http = Curl::of( $this->clock, $this->config->streamCapabilities(), + $this->config->io(), ); return $this->http = $this->config->maxHttpConcurrency()->match( From 5ede4b8e7af18a131c1d1d6e6fbc338448915811 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:36:59 +0200 Subject: [PATCH 12/17] force using the clock from the config --- src/OperatingSystem/Unix.php | 1 - src/Remote/Generic.php | 16 +++++----------- tests/Remote/GenericTest.php | 7 ------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/OperatingSystem/Unix.php b/src/OperatingSystem/Unix.php index f2cf627..6fd8c6b 100644 --- a/src/OperatingSystem/Unix.php +++ b/src/OperatingSystem/Unix.php @@ -90,7 +90,6 @@ public function remote(): Remote { return $this->remote ??= Remote\Generic::of( $this->control(), - $this->clock(), $this->config, ); } diff --git a/src/Remote/Generic.php b/src/Remote/Generic.php index 766d07e..e4625c9 100644 --- a/src/Remote/Generic.php +++ b/src/Remote/Generic.php @@ -11,7 +11,6 @@ Server, Servers, }; -use Innmind\TimeContinuum\Clock; use Innmind\Socket\{ Internet\Transport, Client, @@ -31,23 +30,18 @@ final class Generic implements Remote { private Server $server; - private Clock $clock; private Config $config; private ?HttpTransport $http = null; - private function __construct(Server $server, Clock $clock, Config $config) + private function __construct(Server $server, Config $config) { $this->server = $server; - $this->clock = $clock; $this->config = $config; } - public static function of( - Server $server, - Clock $clock, - Config $config, - ): self { - return new self($server, $clock, $config); + public static function of(Server $server, Config $config): self + { + return new self($server, $config); } public function ssh(Url $server): Server @@ -79,7 +73,7 @@ public function http(): HttpTransport } $http = Curl::of( - $this->clock, + $this->config->clock(), $this->config->streamCapabilities(), $this->config->io(), ); diff --git a/tests/Remote/GenericTest.php b/tests/Remote/GenericTest.php index c026f60..303466b 100644 --- a/tests/Remote/GenericTest.php +++ b/tests/Remote/GenericTest.php @@ -17,7 +17,6 @@ Url, Authority\Port, }; -use Innmind\TimeContinuum\Clock; use Innmind\Socket\{ Internet\Transport, Client\Internet, @@ -40,7 +39,6 @@ public function testInterface() Remote::class, Generic::of( $this->createMock(Server::class), - $this->createMock(Clock::class), Config::of(), ), ); @@ -50,7 +48,6 @@ public function testSsh() { $remote = Generic::of( $server = $this->createMock(Server::class), - $this->createMock(Clock::class), Config::of(), ); $server @@ -74,7 +71,6 @@ public function testSshWithoutPort() { $remote = Generic::of( $server = $this->createMock(Server::class), - $this->createMock(Clock::class), Config::of(), ); $server @@ -98,7 +94,6 @@ public function testSocket() { $remote = Generic::of( $this->createMock(Server::class), - $this->createMock(Clock::class), Config::of(), ); $server = InternetServer::of(Transport::tcp(), IPv4::localhost(), Port::of(1234))->match( @@ -120,7 +115,6 @@ public function testHttp() { $remote = Generic::of( $this->createMock(Server::class), - $this->createMock(Clock::class), Config::of(), ); @@ -137,7 +131,6 @@ public function testSql() ->then(function($server) { $remote = Generic::of( $this->createMock(Server::class), - $this->createMock(Clock::class), Config::of(), ); From 65476c03e0fda0b724c63cd9721cb5aee4740876 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:49:49 +0200 Subject: [PATCH 13/17] add OperatingSystem::map() --- CHANGELOG.md | 4 ++++ src/OperatingSystem.php | 7 +++++++ src/OperatingSystem/Logger.php | 8 ++++++++ src/OperatingSystem/Resilient.php | 5 +++++ src/OperatingSystem/Unix.php | 5 +++++ tests/OperatingSystem/LoggerTest.php | 16 +++++++++++++++- tests/OperatingSystem/ResilientTest.php | 16 ++++++++++++++++ tests/OperatingSystem/UnixTest.php | 15 +++++++++++++++ 8 files changed, 75 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f94e90..a32856a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- `Innmind\OperatingSystem\OperatingSystem::map()` + ### Changed - `Innmind\OperatingSystem\Factory::build()` now only accept a `Config` object, use `Config::withClock()` to change the default clock diff --git a/src/OperatingSystem.php b/src/OperatingSystem.php index b057fcd..8e24a51 100644 --- a/src/OperatingSystem.php +++ b/src/OperatingSystem.php @@ -9,6 +9,13 @@ interface OperatingSystem { + /** + * This method allows to change the underlying OS implementation while being + * able to keep any decorators on top of it. + * + * @param callable(self, Config): self $map + */ + public function map(callable $map): self; public function clock(): Clock; public function filesystem(): Filesystem; public function status(): ServerStatus; diff --git a/src/OperatingSystem/Logger.php b/src/OperatingSystem/Logger.php index f413584..207f71d 100644 --- a/src/OperatingSystem/Logger.php +++ b/src/OperatingSystem/Logger.php @@ -32,6 +32,14 @@ public static function psr(OperatingSystem $os, LoggerInterface $logger): self return new self($os, $logger); } + public function map(callable $map): OperatingSystem + { + return new self( + $this->os->map($map), + $this->logger, + ); + } + public function clock(): TimeContinuum\Clock { return new TimeContinuum\Logger\Clock( diff --git a/src/OperatingSystem/Resilient.php b/src/OperatingSystem/Resilient.php index ff1f527..a0471a5 100644 --- a/src/OperatingSystem/Resilient.php +++ b/src/OperatingSystem/Resilient.php @@ -32,6 +32,11 @@ public static function of(OperatingSystem $os): self return new self($os); } + public function map(callable $map): OperatingSystem + { + return new self($this->os->map($map)); + } + public function clock(): Clock { return $this->os->clock(); diff --git a/src/OperatingSystem/Unix.php b/src/OperatingSystem/Unix.php index 6fd8c6b..5604b64 100644 --- a/src/OperatingSystem/Unix.php +++ b/src/OperatingSystem/Unix.php @@ -44,6 +44,11 @@ public static function of(Config $config = null): self return new self($config ?? Config::of()); } + public function map(callable $map): OperatingSystem + { + return $map($this, $this->config); + } + public function clock(): Clock { return $this->config->clock(); diff --git a/tests/OperatingSystem/LoggerTest.php b/tests/OperatingSystem/LoggerTest.php index 6676244..1c1719a 100644 --- a/tests/OperatingSystem/LoggerTest.php +++ b/tests/OperatingSystem/LoggerTest.php @@ -5,6 +5,7 @@ use Innmind\OperatingSystem\{ OperatingSystem\Logger, + OperatingSystem\Unix, OperatingSystem, Filesystem, Sockets, @@ -27,11 +28,12 @@ class LoggerTest extends TestCase use BlackBox; private OperatingSystem $os; + private OperatingSystem $underlying; public function setUp(): void { $this->os = Logger::psr( - $this->createMock(OperatingSystem::class), + $this->underlying = Unix::of(), $this->createMock(LoggerInterface::class), ); } @@ -107,4 +109,16 @@ public function testProcess() $this->os->process(), ); } + + public function testMap() + { + $result = $this->os->map(function($os) { + $this->assertSame($this->underlying, $os); + + return Unix::of(); + }); + + $this->assertInstanceOf(Logger::class, $result); + $this->assertNotSame($this->os, $result); + } } diff --git a/tests/OperatingSystem/ResilientTest.php b/tests/OperatingSystem/ResilientTest.php index 15b1fc5..180443d 100644 --- a/tests/OperatingSystem/ResilientTest.php +++ b/tests/OperatingSystem/ResilientTest.php @@ -5,6 +5,7 @@ use Innmind\OperatingSystem\{ OperatingSystem\Resilient, + OperatingSystem\Unix, OperatingSystem, Filesystem, Ports, @@ -33,4 +34,19 @@ public function testInterface() $this->assertInstanceOf(Remote\Resilient::class, $os->remote()); $this->assertInstanceOf(CurrentProcess::class, $os->process()); } + + public function testMap() + { + $underlying = Unix::of(); + $os = Resilient::of($underlying); + + $result = $os->map(function($os) use ($underlying) { + $this->assertSame($underlying, $os); + + return Unix::of(); + }); + + $this->assertInstanceOf(Resilient::class, $result); + $this->assertNotSame($os, $result); + } } diff --git a/tests/OperatingSystem/UnixTest.php b/tests/OperatingSystem/UnixTest.php index 2596b38..e86bc73 100644 --- a/tests/OperatingSystem/UnixTest.php +++ b/tests/OperatingSystem/UnixTest.php @@ -43,4 +43,19 @@ public function testInterface() $this->assertSame($os->remote(), $os->remote()); $this->assertSame($os->process(), $os->process()); } + + public function testMap() + { + $os = Unix::of($config = Config::of()); + $expected = Unix::of(); + + $result = $os->map(function($os_, $config_) use ($os, $config, $expected) { + $this->assertSame($os, $os_); + $this->assertSame($config, $config_); + + return $expected; + }); + + $this->assertSame($expected, $result); + } } From 167534a34ec2b593fdf6d12f33bd6ed94d5c8037 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 17:59:00 +0200 Subject: [PATCH 14/17] use the Config to specify the way to halt the process --- CHANGELOG.md | 1 + src/Config.php | 34 ++++++++++++++++++++++++++++++++ src/Filesystem/Generic.php | 19 ++++++------------ src/OperatingSystem/Unix.php | 6 ++---- tests/Filesystem/GenericTest.php | 9 --------- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a32856a..70aad2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - `Innmind\OperatingSystem\OperatingSystem::map()` +- `Innmind\OperatingSystem\Config::haltProcessVia()` ### Changed diff --git a/src/Config.php b/src/Config.php index a9c35de..973338a 100644 --- a/src/Config.php +++ b/src/Config.php @@ -10,6 +10,7 @@ }; use Innmind\Filesystem\CaseSensitivity; use Innmind\Server\Status\EnvironmentPath; +use Innmind\TimeWarp\Halt; use Innmind\IO\IO; use Innmind\Stream\{ Capabilities, @@ -23,6 +24,7 @@ final class Config private CaseSensitivity $caseSensitivity; private Capabilities $streamCapabilities; private IO $io; + private Halt $halt; private EnvironmentPath $path; /** @var Maybe */ private Maybe $maxHttpConcurrency; @@ -35,6 +37,7 @@ private function __construct( CaseSensitivity $caseSensitivity, Capabilities $streamCapabilities, IO $io, + Halt $halt, EnvironmentPath $path, Maybe $maxHttpConcurrency, ) { @@ -42,6 +45,7 @@ private function __construct( $this->caseSensitivity = $caseSensitivity; $this->streamCapabilities = $streamCapabilities; $this->io = $io; + $this->halt = $halt; $this->path = $path; $this->maxHttpConcurrency = $maxHttpConcurrency; } @@ -59,6 +63,7 @@ public static function of(): self null => $streams->watch()->waitForever(), default => $streams->watch()->timeoutAfter($timeout), }), + new Halt\Usleep, EnvironmentPath::of(\getenv('PATH') ?: ''), $maxHttpConcurrency, ); @@ -74,6 +79,7 @@ public function withClock(Clock $clock): self $this->caseSensitivity, $this->streamCapabilities, $this->io, + $this->halt, $this->path, $this->maxHttpConcurrency, ); @@ -89,6 +95,7 @@ public function caseInsensitiveFilesystem(): self CaseSensitivity::insensitive, $this->streamCapabilities, $this->io, + $this->halt, $this->path, $this->maxHttpConcurrency, ); @@ -108,6 +115,23 @@ public function useStreamCapabilities(Capabilities $capabilities): self null => $capabilities->watch()->waitForever(), default => $capabilities->watch()->timeoutAfter($timeout), }), + $this->halt, + $this->path, + $this->maxHttpConcurrency, + ); + } + + /** + * @psalm-mutation-free + */ + public function haltProcessVia(Halt $halt): self + { + return new self( + $this->clock, + $this->caseSensitivity, + $this->streamCapabilities, + $this->io, + $halt, $this->path, $this->maxHttpConcurrency, ); @@ -123,6 +147,7 @@ public function withEnvironmentPath(EnvironmentPath $path): self $this->caseSensitivity, $this->streamCapabilities, $this->io, + $this->halt, $path, $this->maxHttpConcurrency, ); @@ -140,6 +165,7 @@ public function limitHttpConcurrencyTo(int $max): self $this->caseSensitivity, $this->streamCapabilities, $this->io, + $this->halt, $this->path, Maybe::just($max), ); @@ -177,6 +203,14 @@ public function io(): IO return $this->io; } + /** + * @internal + */ + public function halt(): Halt + { + return $this->halt; + } + /** * @internal */ diff --git a/src/Filesystem/Generic.php b/src/Filesystem/Generic.php index bd60a62..40033b4 100644 --- a/src/Filesystem/Generic.php +++ b/src/Filesystem/Generic.php @@ -10,7 +10,6 @@ use Innmind\Filesystem\Adapter; use Innmind\Url\Path; use Innmind\Server\Control\Server\Processes; -use Innmind\TimeWarp\Halt; use Innmind\FileWatch\{ Ping, Factory, @@ -25,23 +24,17 @@ final class Generic implements Filesystem /** @var \WeakMap */ private \WeakMap $mounted; - private function __construct( - Processes $processes, - Halt $halt, - Config $config, - ) { - $this->watch = Factory::build($processes, $halt); + private function __construct(Processes $processes, Config $config) + { + $this->watch = Factory::build($processes, $config->halt()); $this->config = $config; /** @var \WeakMap */ $this->mounted = new \WeakMap; } - public static function of( - Processes $processes, - Halt $halt, - Config $config, - ): self { - return new self($processes, $halt, $config); + public static function of(Processes $processes, Config $config): self + { + return new self($processes, $config); } public function mount(Path $path): Adapter diff --git a/src/OperatingSystem/Unix.php b/src/OperatingSystem/Unix.php index 5604b64..6ee0505 100644 --- a/src/OperatingSystem/Unix.php +++ b/src/OperatingSystem/Unix.php @@ -21,7 +21,6 @@ Servers, }; use Innmind\TimeContinuum\Clock; -use Innmind\TimeWarp\Halt\Usleep; final class Unix implements OperatingSystem { @@ -58,7 +57,6 @@ public function filesystem(): Filesystem { return $this->filesystem ??= Filesystem\Generic::of( $this->control()->processes(), - new Usleep, $this->config, ); } @@ -77,7 +75,7 @@ public function control(): ServerControl return $this->control ??= Servers\Unix::of( $this->clock(), $this->config->streamCapabilities(), - new Usleep, + $this->config->halt(), ); } @@ -101,6 +99,6 @@ public function remote(): Remote public function process(): CurrentProcess { - return $this->process ??= CurrentProcess\Generic::of(new Usleep); + return $this->process ??= CurrentProcess\Generic::of($this->config->halt()); } } diff --git a/tests/Filesystem/GenericTest.php b/tests/Filesystem/GenericTest.php index 013b2f6..f72be3a 100644 --- a/tests/Filesystem/GenericTest.php +++ b/tests/Filesystem/GenericTest.php @@ -11,7 +11,6 @@ use Innmind\Filesystem\Adapter\Filesystem as FilesystemAdapter; use Innmind\Url\Path; use Innmind\Server\Control\Server\Processes; -use Innmind\TimeWarp\Halt; use Innmind\FileWatch\Ping; use Fixtures\Innmind\Url\Path as FPath; use PHPUnit\Framework\TestCase; @@ -27,7 +26,6 @@ public function testInterface() Filesystem::class, Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ), ); @@ -37,7 +35,6 @@ public function testMount() { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); @@ -50,7 +47,6 @@ public function testMountingTheSamePathTwiceReturnsTheSameAdapter() { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); @@ -63,7 +59,6 @@ public function testContainsFile() { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); @@ -77,7 +72,6 @@ public function testContainsDirectory() { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); @@ -91,7 +85,6 @@ public function testWatch() { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); @@ -105,7 +98,6 @@ public function testRequireUnknownFile() ->then(function($path) { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); @@ -120,7 +112,6 @@ public function testRequireFile() { $filesystem = Generic::of( $this->createMock(Processes::class), - $this->createMock(Halt::class), Config::of(), ); From afff687dd811fffa98468d3d9e5ebe8a9f047cdb Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 18:01:21 +0200 Subject: [PATCH 15/17] remove useless annotations --- src/Sockets/Unix.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Sockets/Unix.php b/src/Sockets/Unix.php index 85a3210..2129398 100644 --- a/src/Sockets/Unix.php +++ b/src/Sockets/Unix.php @@ -32,19 +32,16 @@ public static function of(Config $config): self public function open(Address $address): Maybe { - /** @var Maybe */ return Server\Unix::of($address); } public function takeOver(Address $address): Maybe { - /** @var Maybe */ return Server\Unix::recoverable($address); } public function connectTo(Address $address): Maybe { - /** @var Maybe */ return Client\Unix::of($address); } From d0b85226d21766672cf9b2e2a29c06400f8a2dd3 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 18:15:38 +0200 Subject: [PATCH 16/17] update documentation --- README.md | 54 +-------------------------- documentation/use_cases/filesystem.md | 13 ++++--- documentation/use_cases/http.md | 12 +++--- 3 files changed, 14 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index f60e787..4fc0e3e 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ $adapter = $os->filesystem()->mount(Path::of('/var/data/')); ### Want to list processes running on the system ? -`$os->status()->processes()->all()` will return a map of [`Inmmind\Immutable\Map`](https://github.com/innmind/serverstatus#usage). +`$os->status()->processes()->all()` will return a map of [`Inmmind\Immutable\Set`](https://github.com/innmind/serverstatus#usage). ### Want to run a command on the system ? @@ -140,54 +140,6 @@ $response = $os $os->process()->id(); ``` -### Want to fork the current process ? - -```php -use Innmind\OperatingSystem\CurrentProcess\{ - Child, - ForkFailed, -}; - -$childSide = static function(): void { - try { - // do something in the child process - exit(0); - } catch (\Throwable $e) { - exit(1); - } -}; -$parentSide = static function(Child $child): void { - // do something with the child -}; -$os - ->process() - ->fork() - ->match( - static fn() => $childSide(), - static fn($left) => match (true) { - $left instanceof Child => $parentSide($left), - $left instanceof ForkFailed => throw new \RuntimeException('Unable to fork the process'), - }, - ); -``` - -### Want to wait for child process to finish ? - -```php -use Innmind\OperatingSystem\CurrentProcess\Child; - -$os - ->process() - ->fork() - ->match( - static fn() => \sleep(10), // child side - static fn($left) => match (true) { - $left instanceof Child => $left->wait(), - default => null, - }, - ); -``` - ### Want to pause the current process ? ```php @@ -205,7 +157,3 @@ $os->process()->signals()->listen(Signal::terminate, function() { // handle the signal here }); ``` - -**Note**: when forking the process the child will have all listeners resetted to avoid having the listener called twice (in the parent and the child). - -**Important**: beware when sending a signal right after a fork, there is a [case](tests/CurrentProcess/GenericTest.php#L126) where the listeners can still be called in the child. diff --git a/documentation/use_cases/filesystem.md b/documentation/use_cases/filesystem.md index 83bac9f..e83848c 100644 --- a/documentation/use_cases/filesystem.md +++ b/documentation/use_cases/filesystem.md @@ -35,12 +35,13 @@ use Innmind\Filesystem\{ Name, }; use Innmind\Url\Path; +use Innmind\Immutable\Predicate\Instance; $addUserPicture = function(Adapter $filesystem, string $userId, File $picture): void { $filesystem - ->get(new Name($userId)) - ->filter(static fn($file) => $file instanceof Directory) - ->otherwise(static fn() => Directory\Directory::named($userId)) + ->get(Name::of($userId)) + ->keep(Instance::of(Directory::class)) + ->otherwise(static fn() => Directory::named($userId)) ->map(static fn($directory) => $directory->add($picture)) ->match( static fn($directory) => $filesystem->add($directory), @@ -50,10 +51,10 @@ $addUserPicture = function(Adapter $filesystem, string $userId, File $picture): $addUserPicture( $os->filesystem()->mount(Path::of('/path/to/users/data/')), 'some-unique-id', - File\File::named( + File::named( 'picture.png', - Content\AtPath::of( - Path::of($_FILES['some_file']['tmp_name']), + Content::ofString( + \file_get_contents($_FILES['some_file']['tmp_name']), ), ), ); diff --git a/documentation/use_cases/http.md b/documentation/use_cases/http.md index cec0d28..6673ef5 100644 --- a/documentation/use_cases/http.md +++ b/documentation/use_cases/http.md @@ -4,16 +4,16 @@ ```php use Innmind\Http\{ - Message\Request\Request, - Message\Method, - Message\Response, + Request, + Method, + Response, ProtocolVersion, }; use Innmind\Url\Url; $http = $os->remote()->http(); -$response = $http(new Request( +$response = $http(Request::of( Url::of('https://github.com'), Method::get, ProtocolVersion::v20, @@ -38,7 +38,7 @@ One of the first things taught when working with distributed systems is that the use Innmind\OperatingSystem\OperatingSystem\Resilient; use Innmind\HttpTransport\ExponentialBackoff; -$os = new Resilient($os); +$os = Resilient::of($os); $http = $os->remote()->http(); $http instanceof ExponentialBackoff; // true ``` @@ -54,7 +54,7 @@ $http = CircuitBreaker::of( $os->clock(), new Minute(1), ); -$request = new Request(/* ...args */) +$request = Request::of(/* ...args */) $response = $http($request); // if the previous call failed then the next call wil not even be sent to the // server and the client will respond immediately unless 1 minute has elapsed From 1b3e2da197b55faf5f7610e7fbc39234648f3534 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 22 Oct 2023 18:22:26 +0200 Subject: [PATCH 17/17] specify next release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70aad2d..170b0eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## 4.0.0 - 2023-10-22 ### Added