Extract components and add more tests

This commit is contained in:
2020-12-12 02:11:05 +01:00
parent 600f52567f
commit 92bc0ab407
22 changed files with 598 additions and 149 deletions

43
src/Task/Interval.php Normal file
View File

@@ -0,0 +1,43 @@
<?php
namespace Toalett\Multiprocessing\Task;
use Toalett\Multiprocessing\Exception\InvalidArgumentException;
class Interval
{
private float $seconds;
private function __construct(float $seconds)
{
if ($seconds <= 0) {
throw new InvalidArgumentException('positive float', $seconds);
}
$this->seconds = $seconds;
}
public static function seconds(float $seconds): self
{
return new self($seconds);
}
public static function minutes(float $minutes): self
{
return new self(60.0 * $minutes);
}
public static function hours(float $hours): self
{
return new self(3600.0 * $hours);
}
public function asFloat(): float
{
return $this->seconds;
}
public function asInt(): int
{
return (int)$this->seconds;
}
}

22
src/Task/RepeatedTask.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
namespace Toalett\Multiprocessing\Task;
use React\EventLoop\LoopInterface;
use React\EventLoop\TimerInterface;
class RepeatedTask extends Task
{
public Interval $interval;
public function __construct(Interval $interval, callable $callable, ...$arguments)
{
$this->interval = $interval;
parent::__construct($callable, $arguments);
}
protected function generateTimer(LoopInterface $loop): TimerInterface
{
return $loop->addPeriodicTimer($this->interval->asFloat(), $this->createDeferredCall());
}
}

48
src/Task/Task.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
namespace Toalett\Multiprocessing\Task;
use React\EventLoop\LoopInterface;
use React\EventLoop\TimerInterface;
abstract class Task
{
public $callable;
public array $arguments;
protected ?TimerInterface $timer = null;
public function __construct(callable $callable, ...$arguments)
{
$this->callable = $callable;
$this->arguments = $arguments;
}
abstract protected function generateTimer(LoopInterface $loop): TimerInterface;
protected function createDeferredCall(): callable
{
return fn() => call_user_func_array(
$this->callable,
$this->arguments
);
}
public function enable(LoopInterface $loop): void
{
if (!$this->isBound()) {
$this->timer = $this->generateTimer($loop);
}
}
public function isBound(): bool
{
return !is_null($this->timer);
}
public function cancel(LoopInterface $loop): void
{
if ($this->isBound()) {
$loop->cancelTimer($this->timer);
}
}
}

37
src/Task/Tasks.php Normal file
View File

@@ -0,0 +1,37 @@
<?php
namespace Toalett\Multiprocessing\Task;
use React\EventLoop\LoopInterface;
class Tasks
{
/** @var Task[] */
private array $tasks;
private ?LoopInterface $loop = null;
public function __construct(Task ...$tasks)
{
$this->tasks = $tasks;
}
public function enable(LoopInterface $loop): void
{
if (is_null($this->loop)) {
$this->loop = $loop;
foreach ($this->tasks as $task) {
$task->enable($this->loop);
}
}
}
public function cancel(): void
{
if (!is_null($this->loop)) {
foreach ($this->tasks as $task) {
$task->cancel($this->loop);
}
$this->loop = null;
}
}
}