83 lines
2.0 KiB
PHP
83 lines
2.0 KiB
PHP
<?php
|
|
namespace nur\sery\app;
|
|
|
|
use nur\sery\os\proc\Cmd;
|
|
use nur\sery\output\msg;
|
|
use nur\sery\StateException;
|
|
|
|
class launcher {
|
|
static function launch(string $appClass, ...$args): int {
|
|
$cmd = new Cmd([
|
|
__DIR__."/../../lib/launch.php",
|
|
$appClass,
|
|
...$args,
|
|
]);
|
|
$cmd->addRedir("null");
|
|
$cmd->passthru($exitcode);
|
|
return $exitcode;
|
|
}
|
|
|
|
static function _start(array $args, Runfile $runfile): bool {
|
|
if ($runfile->isLocked()) return false;
|
|
$pid = pcntl_fork();
|
|
if ($pid == -1) {
|
|
# parent, impossible de forker
|
|
throw new StateException("unable to fork");
|
|
} elseif ($pid) {
|
|
# parent, fork ok
|
|
return true;
|
|
} else {
|
|
## child, fork ok
|
|
# Créer un groupe de process, pour pouvoir les tuer toutes en même temps
|
|
$runfile->tm_startPg();
|
|
$exitcode = -776;
|
|
try {
|
|
# puis lancer la commande
|
|
$cmd = new Cmd($args);
|
|
#XXX fichier de log?
|
|
#XXX charger /g/init.env
|
|
$cmd->addSource("/g/init.env");
|
|
$cmd->addRedir("null");
|
|
$cmd->fork_exec($exitcode);
|
|
return true;
|
|
} finally {
|
|
$runfile->wfStopped($exitcode);
|
|
}
|
|
}
|
|
}
|
|
|
|
static function _stop(Runfile $runfile): void {
|
|
$data = $runfile->read();
|
|
$pid = $data["pg_pid"];
|
|
if ($pid === null) {
|
|
msg::warning("$data[name]: groupe de process inconnu");
|
|
return;
|
|
}
|
|
msg::action("kill $pid");
|
|
if (!posix_kill(-$pid, SIGKILL)) {
|
|
switch (posix_get_last_error()) {
|
|
case PCNTL_ESRCH:
|
|
msg::afailure("process inexistant");
|
|
break;
|
|
case PCNTL_EPERM:
|
|
msg::afailure("process non accessible");
|
|
break;
|
|
case PCNTL_EINVAL:
|
|
msg::afailure("signal invalide");
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
$timeout = 10;
|
|
while ($runfile->tm_isUndead($pid)) {
|
|
sleep(1);
|
|
if (--$timeout == 0) {
|
|
msg::afailure("impossible d'arrêter la tâche");
|
|
return;
|
|
}
|
|
}
|
|
$runfile->wfStopped(-778);
|
|
msg::asuccess();
|
|
}
|
|
}
|