Skip to content

Commit

Permalink
Merge pull request #34 from FluffyDiscord/#why-not-count
Browse files Browse the repository at this point in the history
Feat: add callback to check how many workers are available
  • Loading branch information
msmakouz authored Feb 23, 2024
2 parents 605e258 + 6791dc9 commit 0014c41
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 2 deletions.
29 changes: 29 additions & 0 deletions src/Informer/Worker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Spiral\RoadRunner\Informer;

final class Worker
{
/**
* @param positive-int $pid process id
* @param int $statusCode integer status of the worker
* @param int $executions number of worker executions
* @param positive-int $createdAt unix nano timestamp of worker creation time
* @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
*/
public function __construct(
public int $pid,
public int $statusCode,
public int $executions,
public int $createdAt,
public int $memoryUsage,
public float $cpuUsage,
public string $command,
public string $status,
) {
}
}
21 changes: 21 additions & 0 deletions src/Informer/Workers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Spiral\RoadRunner\Informer;

final class Workers implements \Countable
{
/**
* @param array<Worker> $workers
*/
public function __construct(
public array $workers = [],
) {
}

public function count(): int
{
return \count($this->workers);
}
}
50 changes: 50 additions & 0 deletions src/WorkerPool.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,6 +41,42 @@ public function addWorker(string $plugin): void
$this->rpc->call('informer.AddWorker', $plugin);
}

/**
* Get the number of workers for the pool.
*
* @param non-empty-string $plugin
*/
public function countWorkers(string $plugin): int
{
return \count($this->getWorkers($plugin));
}

/**
* Get the info about running workers for the pool.
*
* @param non-empty-string $plugin
*/
public function getWorkers(string $plugin): Workers
{
/**
* @var array{workers: list<TInformerWorker>} $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']));
}

/**
* Remove worker from the pool.
*
Expand Down
75 changes: 73 additions & 2 deletions tests/Unit/WorkerPoolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
}
Expand All @@ -35,10 +53,63 @@ public function testAddWorker(): void
$this->workerPool->addWorker('test');
}

#[DataProvider('countDataProvider')]
public function testCountWorkers(int $expected, array $workers): void
{
$this->rpc
->expects($this->once())
->method('call')
->with('informer.Workers', 'test')
->willReturn(['workers' => $workers]);

$this->assertSame($expected, $this->workerPool->countWorkers('test'));
}

#[DataProvider('getWorkersDataProvider')]
public function testGetWorkers(array $expected, array $workers): void
{
$this->rpc
->expects($this->once())
->method('call')
->with('informer.Workers', 'test')
->willReturn(['workers' => $workers]);

$this->assertEquals(new Workers($expected), $this->workerPool->getWorkers('test'));
}

public function testRemoveWorker(): void
{
$this->rpc->expects($this->once())->method('call')->with('informer.RemoveWorker', 'test');

$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]];
}
}

0 comments on commit 0014c41

Please sign in to comment.