summaryrefslogtreecommitdiffstats
path: root/vendor/gipfl/process
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:44:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:44:51 +0000
commita1ec78bf0dc93d0e05e5f066f1949dc3baecea06 (patch)
treeee596ce1bc9840661386f96f9b8d1f919a106317 /vendor/gipfl/process
parentInitial commit. (diff)
downloadicingaweb2-module-incubator-upstream/0.20.0.tar.xz
icingaweb2-module-incubator-upstream/0.20.0.zip
Adding upstream version 0.20.0.upstream/0.20.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gipfl/process')
-rw-r--r--vendor/gipfl/process/composer.json25
-rw-r--r--vendor/gipfl/process/src/FinishedProcessState.php66
-rw-r--r--vendor/gipfl/process/src/ProcessInfo.php89
-rw-r--r--vendor/gipfl/process/src/ProcessKiller.php81
-rw-r--r--vendor/gipfl/process/src/ProcessList.php44
5 files changed, 305 insertions, 0 deletions
diff --git a/vendor/gipfl/process/composer.json b/vendor/gipfl/process/composer.json
new file mode 100644
index 0000000..21e9971
--- /dev/null
+++ b/vendor/gipfl/process/composer.json
@@ -0,0 +1,25 @@
+{
+ "name": "gipfl/process",
+ "description": "Process-related utility classes",
+ "type": "library",
+ "license": "MIT",
+ "autoload": {
+ "psr-4": {
+ "gipfl\\Process\\": "src/"
+ }
+ },
+ "authors": [
+ {
+ "name": "Thomas Gelf",
+ "email": "thomas@gelf.net"
+ }
+ ],
+ "require": {
+ "php": ">=5.6.0",
+ "ext-json": "*",
+ "react/child-process": ">=0.6",
+ "react/promise": "^2",
+ "gipfl/json": ">=0.1",
+ "gipfl/linux-health": ">=0.2"
+ }
+}
diff --git a/vendor/gipfl/process/src/FinishedProcessState.php b/vendor/gipfl/process/src/FinishedProcessState.php
new file mode 100644
index 0000000..fd70292
--- /dev/null
+++ b/vendor/gipfl/process/src/FinishedProcessState.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace gipfl\Process;
+
+class FinishedProcessState
+{
+ /** @var int|null */
+ protected $exitCode;
+
+ /** @var int|null */
+ protected $termSignal;
+
+ public function __construct($exitCode, $termSignal)
+ {
+ $this->exitCode = $exitCode;
+ $this->termSignal = $termSignal;
+ }
+
+ public function succeeded()
+ {
+ return $this->exitCode === 0;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getExitCode()
+ {
+ return $this->exitCode;
+ }
+
+ public function getTermSignal()
+ {
+ return $this->termSignal;
+ }
+
+ public function getCombinedExitCode()
+ {
+ if ($this->exitCode === null) {
+ if ($this->termSignal === null) {
+ return 255;
+ } else {
+ return 255 + $this->termSignal;
+ }
+ } else {
+ return $this->exitCode;
+ }
+ }
+
+ public function getReason()
+ {
+ if ($this->exitCode === null) {
+ if ($this->termSignal === null) {
+ return 'Process died';
+ } else {
+ return 'Process got terminated with SIGNAL ' . $this->termSignal;
+ }
+ } else {
+ if ($this->exitCode === 0) {
+ return 'Process finished successfully';
+ } else {
+ return 'Process exited with exit code ' . $this->exitCode;
+ }
+ }
+ }
+}
diff --git a/vendor/gipfl/process/src/ProcessInfo.php b/vendor/gipfl/process/src/ProcessInfo.php
new file mode 100644
index 0000000..db740d1
--- /dev/null
+++ b/vendor/gipfl/process/src/ProcessInfo.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace gipfl\Process;
+
+use gipfl\Json\JsonSerialization;
+use gipfl\LinuxHealth\Memory;
+use React\ChildProcess\Process;
+
+class ProcessInfo implements JsonSerialization
+{
+ /** @var ?int */
+ protected $pid;
+
+ /** @var string */
+ protected $command;
+
+ /** @var bool */
+ protected $running;
+
+ /** @var ?object */
+ protected $memory;
+
+ public static function forProcess(Process $process)
+ {
+ $self = new static();
+ $self->pid = $process->getPid();
+ $self->command = $process->getCommand();
+ $self->running = $process->isRunning();
+ if ($memory = Memory::getUsageForPid($self->pid)) {
+ $self->memory = $memory;
+ }
+
+ return $self;
+ }
+
+ public static function fromSerialization($any)
+ {
+ $self = new static();
+ $self->pid = $any->pid;
+ $self->command = $any->command;
+ $self->running = $any->running;
+ $self->memory = $any->memory;
+
+ return $self;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getPid()
+ {
+ return $this->pid;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRunning()
+ {
+ return $this->running;
+ }
+
+ /**
+ * @return object|null
+ */
+ public function getMemory()
+ {
+ return $this->memory;
+ }
+
+ #[\ReturnTypeWillChange]
+ public function jsonSerialize()
+ {
+ return (object) [
+ 'pid' => $this->pid,
+ 'command' => $this->command,
+ 'running' => $this->running,
+ 'memory' => $this->memory,
+ ];
+ }
+}
diff --git a/vendor/gipfl/process/src/ProcessKiller.php b/vendor/gipfl/process/src/ProcessKiller.php
new file mode 100644
index 0000000..cf904ce
--- /dev/null
+++ b/vendor/gipfl/process/src/ProcessKiller.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace gipfl\Process;
+
+use React\ChildProcess\Process as ChildProcess;
+use React\EventLoop\LoopInterface;
+use React\Promise\Deferred;
+use function React\Promise\resolve;
+
+class ProcessKiller
+{
+ /**
+ * @param ChildProcess $process
+ * @param LoopInterface $loop
+ * @param int $timeout
+ * @return \React\Promise\ExtendedPromiseInterface
+ */
+ public static function terminateProcess(ChildProcess $process, LoopInterface $loop, $timeout = 0)
+ {
+ $processes = new ProcessList();
+ $processes->attach($process);
+ return static::terminateProcesses($processes, $loop, $timeout);
+ }
+
+ /**
+ * @param ProcessList $processes
+ * @param LoopInterface $loop
+ * @param int $timeout
+ * @return \React\Promise\ExtendedPromiseInterface
+ */
+ public static function terminateProcesses(ProcessList $processes, LoopInterface $loop, $timeout = 5)
+ {
+ if ($processes->count() === 0) {
+ return resolve();
+ }
+ $deferred = new Deferred();
+ $killTimer = $loop->addTimer($timeout, function () use ($deferred, $processes, $loop) {
+ /** @var ChildProcess $process */
+ foreach ($processes as $process) {
+ $pid = $process->getPid();
+ // Logger::error("Process $pid is still running, sending SIGKILL");
+ $process->terminate(SIGKILL);
+ }
+
+ // Let's add a bit of a delay after KILLing
+ $loop->addTimer(0.1, function () use ($deferred) {
+ $deferred->resolve();
+ });
+ });
+
+ $timer = $loop->addPeriodicTimer($timeout / 20, function () use (
+ $deferred,
+ $processes,
+ $loop,
+ &$timer,
+ $killTimer
+ ) {
+ $stopped = [];
+ /** @var ChildProcess $process */
+ foreach ($processes as $process) {
+ if (! $process->isRunning()) {
+ $stopped[] = $process;
+ }
+ }
+ foreach ($stopped as $process) {
+ $processes->detach($process);
+ }
+ if ($processes->count() === 0) {
+ $loop->cancelTimer($timer);
+ $loop->cancelTimer($killTimer);
+ $deferred->resolve();
+ }
+ });
+ /** @var ChildProcess $process */
+ foreach ($processes as $process) {
+ $process->terminate(SIGTERM);
+ }
+
+ return $deferred->promise();
+ }
+}
diff --git a/vendor/gipfl/process/src/ProcessList.php b/vendor/gipfl/process/src/ProcessList.php
new file mode 100644
index 0000000..a3f7c30
--- /dev/null
+++ b/vendor/gipfl/process/src/ProcessList.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace gipfl\Process;
+
+/**
+ * @method ChildProcess current
+ */
+use Evenement\EventEmitterInterface;
+use Evenement\EventEmitterTrait;
+use InvalidArgumentException;
+use React\ChildProcess\Process as ChildProcess;
+use SplObjectStorage;
+
+class ProcessList extends SplObjectStorage implements EventEmitterInterface
+{
+ const ON_ATTACHED = 'attached';
+ const ON_DETACHED = 'detached';
+
+ use EventEmitterTrait;
+
+ #[\ReturnTypeWillChange]
+ public function attach($object, $info = null)
+ {
+ if (! $object instanceof ChildProcess || $info !== null) {
+ throw new InvalidArgumentException(sprintf(
+ 'Can attach only %s instances',
+ ChildProcess::class
+ ));
+ }
+ $object->on('exit', function () use ($object) {
+ $this->detach($object);
+ });
+
+ parent::attach($object, $info);
+ $this->emit(self::ON_ATTACHED, [$object]);
+ }
+
+ #[\ReturnTypeWillChange]
+ public function detach($object)
+ {
+ parent::detach($object);
+ $this->emit(self::ON_DETACHED, [$object]);
+ }
+}