From 35697bfedfceccb431763c9a2502981042621720 Mon Sep 17 00:00:00 2001 From: kaleta Date: Wed, 21 Feb 2024 17:43:34 +0100 Subject: [PATCH 1/5] - feat: add callback to check how many workers are available --- src/WorkerPool.php | 10 ++++++++++ tests/Unit/WorkerPoolTest.php | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/WorkerPool.php b/src/WorkerPool.php index 9f2eca3..624e936 100644 --- a/src/WorkerPool.php +++ b/src/WorkerPool.php @@ -27,6 +27,16 @@ public function addWorker(string $plugin): void $this->rpc->call('informer.AddWorker', $plugin); } + /** + * Get the worker count for a pool. + * + * @param non-empty-string $plugin + */ + public function countWorkers(string $plugin): int + { + return (int)($this->rpc->call('informer.Workers', $plugin)['workers'] ?? 0); + } + /** * Remove worker from the pool. * diff --git a/tests/Unit/WorkerPoolTest.php b/tests/Unit/WorkerPoolTest.php index ea72bf2..225d18f 100644 --- a/tests/Unit/WorkerPoolTest.php +++ b/tests/Unit/WorkerPoolTest.php @@ -35,10 +35,17 @@ public function testAddWorker(): void $this->workerPool->addWorker('test'); } + public function testCountWorkers(): void + { + $this->rpc->expects($this->once())->method('call')->with('informer.Workers', 'test'); + + $this->workerPool->countWorkers('test'); + } + public function testRemoveWorker(): void { $this->rpc->expects($this->once())->method('call')->with('informer.RemoveWorker', 'test'); $this->workerPool->removeWorker('test'); } -} \ No newline at end of file +} From 3f8f86675f7f70c14277ac05dbbbc2d3022484e3 Mon Sep 17 00:00:00 2001 From: kaleta Date: Wed, 21 Feb 2024 18:07:21 +0100 Subject: [PATCH 2/5] - feat: add callback to get worker info --- src/WorkerPool.php | 12 +++++++++++- tests/Unit/WorkerPoolTest.php | 9 ++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/WorkerPool.php b/src/WorkerPool.php index 624e936..9fe9d9a 100644 --- a/src/WorkerPool.php +++ b/src/WorkerPool.php @@ -34,7 +34,17 @@ public function addWorker(string $plugin): void */ public function countWorkers(string $plugin): int { - return (int)($this->rpc->call('informer.Workers', $plugin)['workers'] ?? 0); + return count($this->getWorkers($plugin)); + } + + /** + * Get the info about running workers for a pool. + * + * @param non-empty-string $plugin + */ + public function getWorkers(string $plugin): array + { + return $this->rpc->call('informer.Workers', $plugin)['workers']; } /** diff --git a/tests/Unit/WorkerPoolTest.php b/tests/Unit/WorkerPoolTest.php index 225d18f..86a49c3 100644 --- a/tests/Unit/WorkerPoolTest.php +++ b/tests/Unit/WorkerPoolTest.php @@ -37,11 +37,18 @@ public function testAddWorker(): void public function testCountWorkers(): void { - $this->rpc->expects($this->once())->method('call')->with('informer.Workers', 'test'); + $this->rpc->expects($this->once())->method('call')->with('informer.Workers', 'test')->willReturn(['workers' => []]); $this->workerPool->countWorkers('test'); } + public function testGetWorkers(): void + { + $this->rpc->expects($this->once())->method('call')->with('informer.Workers', 'test')->willReturn(['workers' => []]); + + $this->workerPool->getWorkers('test'); + } + public function testRemoveWorker(): void { $this->rpc->expects($this->once())->method('call')->with('informer.RemoveWorker', 'test'); From 680ec4f8760f31a14436163f4c4e2dd532008f0e Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Fri, 23 Feb 2024 00:25:52 +0200 Subject: [PATCH 3/5] Improve code, fix psalm and tests --- src/Informer/Worker.php | 30 +++++++++++++++ src/Informer/Workers.php | 21 +++++++++++ src/WorkerPool.php | 36 ++++++++++++++++-- tests/Unit/WorkerPoolTest.php | 71 +++++++++++++++++++++++++++++++---- 4 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 src/Informer/Worker.php create mode 100644 src/Informer/Workers.php diff --git a/src/Informer/Worker.php b/src/Informer/Worker.php new file mode 100644 index 0000000..d0bb502 --- /dev/null +++ b/src/Informer/Worker.php @@ -0,0 +1,30 @@ + $workers + */ + public function __construct( + public array $workers = [], + ) { + } + + public function count(): int + { + return \count($this->workers); + } +} diff --git a/src/WorkerPool.php b/src/WorkerPool.php index 9fe9d9a..2f20f6b 100644 --- a/src/WorkerPool.php +++ b/src/WorkerPool.php @@ -6,7 +6,21 @@ use Spiral\Goridge\RPC\Codec\JsonCodec; use Spiral\Goridge\RPC\RPCInterface; +use Spiral\RoadRunner\Informer\Workers; +use Spiral\RoadRunner\Informer\Worker as InformerWorker; +/** + * @psalm-type TInformerWorker = array{ + * pid: positive-int, + * status: int, + * numExecs: int, + * created: positive-int, + * memoryUsage: positive-int, + * CPUPercent: float, + * command: string, + * statusStr: string, + * } + */ final class WorkerPool { private readonly RPCInterface $rpc; @@ -34,7 +48,7 @@ public function addWorker(string $plugin): void */ public function countWorkers(string $plugin): int { - return count($this->getWorkers($plugin)); + return \count($this->getWorkers($plugin)); } /** @@ -42,9 +56,25 @@ public function countWorkers(string $plugin): int * * @param non-empty-string $plugin */ - public function getWorkers(string $plugin): array + public function getWorkers(string $plugin): Workers { - return $this->rpc->call('informer.Workers', $plugin)['workers']; + /** + * @var array{workers: list} $data + */ + $data = $this->rpc->call('informer.Workers', $plugin); + + return new Workers(\array_map(static function (array $worker): InformerWorker { + return new InformerWorker( + pid: $worker['pid'], + statusCode: $worker['status'], + executions: $worker['numExecs'], + createdAt: $worker['created'], + memoryUsage: $worker['memoryUsage'], + cpuUsage: $worker['CPUPercent'], + command: $worker['command'], + status: $worker['statusStr'], + ); + }, $data['workers'])); } /** diff --git a/tests/Unit/WorkerPoolTest.php b/tests/Unit/WorkerPoolTest.php index 86a49c3..16c4bbe 100644 --- a/tests/Unit/WorkerPoolTest.php +++ b/tests/Unit/WorkerPoolTest.php @@ -4,14 +4,28 @@ namespace Spiral\RoadRunner\Tests\Worker\Unit; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; use Spiral\Goridge\RPC\Codec\JsonCodec; use Spiral\Goridge\RPC\RPCInterface; +use Spiral\RoadRunner\Informer\Worker; +use Spiral\RoadRunner\Informer\Workers; use Spiral\RoadRunner\WorkerPool; final class WorkerPoolTest extends TestCase { + private const EXAMPLE_WORKER = [ + 'pid' => 1, + 'status' => 1, + 'numExecs' => 1, + 'created' => 1, + 'memoryUsage' => 1, + 'CPUPercent' => 1.0, + 'command' => 'test', + 'statusStr' => 'test', + ]; + private \PHPUnit\Framework\MockObject\MockObject|RPCInterface $rpc; private WorkerPool $workerPool; @@ -23,7 +37,11 @@ protected function setUp(): void parent::setUp(); $this->rpc = $this->createMock(RPCInterface::class); - $this->rpc->expects($this->once())->method('withCodec')->with($this->isInstanceOf(JsonCodec::class))->willReturnSelf(); + $this->rpc + ->expects($this->once()) + ->method('withCodec') + ->with($this->isInstanceOf(JsonCodec::class)) + ->willReturnSelf(); $this->workerPool = new WorkerPool($this->rpc); } @@ -35,18 +53,28 @@ public function testAddWorker(): void $this->workerPool->addWorker('test'); } - public function testCountWorkers(): void + #[DataProvider('countDataProvider')] + public function testCountWorkers(int $expected, array $workers): void { - $this->rpc->expects($this->once())->method('call')->with('informer.Workers', 'test')->willReturn(['workers' => []]); + $this->rpc + ->expects($this->once()) + ->method('call') + ->with('informer.Workers', 'test') + ->willReturn(['workers' => $workers]); - $this->workerPool->countWorkers('test'); + $this->assertSame($expected, $this->workerPool->countWorkers('test')); } - public function testGetWorkers(): void + #[DataProvider('getWorkersDataProvider')] + public function testGetWorkers(array $expected, array $workers): void { - $this->rpc->expects($this->once())->method('call')->with('informer.Workers', 'test')->willReturn(['workers' => []]); + $this->rpc + ->expects($this->once()) + ->method('call') + ->with('informer.Workers', 'test') + ->willReturn(['workers' => $workers]); - $this->workerPool->getWorkers('test'); + $this->assertEquals(new Workers($expected), $this->workerPool->getWorkers('test')); } public function testRemoveWorker(): void @@ -55,4 +83,33 @@ public function testRemoveWorker(): void $this->workerPool->removeWorker('test'); } + + public static function countDataProvider(): \Traversable + { + yield [0, []]; + yield [2, [self::EXAMPLE_WORKER, self::EXAMPLE_WORKER]]; + } + + public static function getWorkersDataProvider(): \Traversable + { + yield [[], []]; + + $workers = \array_map(static function (array $worker): Worker { + return new Worker( + pid: $worker['pid'], + statusCode: $worker['status'], + executions: $worker['numExecs'], + createdAt: $worker['created'], + memoryUsage: $worker['memoryUsage'], + cpuUsage: $worker['CPUPercent'], + command: $worker['command'], + status: $worker['statusStr'], + ); + }, [ + self::EXAMPLE_WORKER, + self::EXAMPLE_WORKER, + ]); + + yield [$workers, [self::EXAMPLE_WORKER, self::EXAMPLE_WORKER]]; + } } From 2cd654f69947748be5309d649aa807ac4d3c1fa2 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Fri, 23 Feb 2024 00:27:37 +0200 Subject: [PATCH 4/5] Remove unused phpdoc --- src/Informer/Worker.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Informer/Worker.php b/src/Informer/Worker.php index d0bb502..2503ee4 100644 --- a/src/Informer/Worker.php +++ b/src/Informer/Worker.php @@ -14,7 +14,6 @@ final class Worker * @param positive-int $memoryUsage memory usage in bytes. Values might vary for different operating systems and based on RSS * @param float $cpuUsage how many percent of the CPU time this process uses * @param string $command used in the service plugin and shows a command for the particular service - * @param string $status */ public function __construct( public int $pid, From 6791dc9834fcc890916e7d4beadf4bbc2ead04f3 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Fri, 23 Feb 2024 00:32:45 +0200 Subject: [PATCH 5/5] Improve comment --- src/WorkerPool.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WorkerPool.php b/src/WorkerPool.php index 2f20f6b..1d201c8 100644 --- a/src/WorkerPool.php +++ b/src/WorkerPool.php @@ -42,7 +42,7 @@ public function addWorker(string $plugin): void } /** - * Get the worker count for a pool. + * Get the number of workers for the pool. * * @param non-empty-string $plugin */ @@ -52,7 +52,7 @@ public function countWorkers(string $plugin): int } /** - * Get the info about running workers for a pool. + * Get the info about running workers for the pool. * * @param non-empty-string $plugin */