modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2024-06-14 13:29:47 +04:00
parent e9ab61b154
commit dca04418b7
5 changed files with 74 additions and 16 deletions

View File

@ -3,7 +3,7 @@
$internalUse = $argv[1] ?? null; $internalUse = $argv[1] ?? null;
if ($internalUse !== "--internal-use") exit("Wrong args"); if ($internalUse !== "--internal-use") exit("Wrong args");
$paramsfile = $argv[2] ?? null; $paramsfile = $argv[2] ?? null;
if (!file_exists($paramsfile)) exit("bad params file"); if (!file_exists($paramsfile)) exit("Bad params file");
$argc -= 2; $argc -= 2;
$argv = array_merge( $argv = array_merge(
array_slice($argv, 0, 1), array_slice($argv, 0, 1),
@ -14,12 +14,14 @@ $app_params = unserialize(file_get_contents($paramsfile));
require $app_params["vendor"]["autoload"]; require $app_params["vendor"]["autoload"];
use nur\cli\Application; use nur\cli\Application;
use nur\sery\output\msg;
use nur\sery\wip\app\app; use nur\sery\wip\app\app;
use nur\sery\app\launcher; use nur\sery\app\launcher;
use nur\yaml; use nur\yaml;
class _LaunchApp extends Application { class _LaunchApp extends Application {
const NAME = "_launch"; const NAME = "_launch";
const USE_LOGFILE = true;
const ACTION_INFOS = 0, ACTION_START = 1, ACTION_STOP = 2; const ACTION_INFOS = 0, ACTION_START = 1, ACTION_STOP = 2;
@ -46,15 +48,18 @@ class _LaunchApp extends Application {
function main() { function main() {
$appClass = $this->args[0] ?? null; $appClass = $this->args[0] ?? null;
if ($appClass === null) { if ($appClass === null) {
self::die("Vous devez spécifier la classe de l'application"); msg::error("Vous devez spécifier la classe de l'application");
self::die();
} elseif (!class_exists($appClass)) { } elseif (!class_exists($appClass)) {
self::die("$appClass: Cette classe n'existe pas"); msg::error("$appClass: Cette classe n'existe pas");
self::die();
} }
$args = array_slice($this->args, 1); $args = array_slice($this->args, 1);
$useRunfile = constant("$appClass::USE_RUNFILE"); $useRunfile = constant("$appClass::USE_RUNFILE");
if (!$useRunfile) { if (!$useRunfile) {
self::die("Cette application ne supporte pas l'usage de runfile"); msg::error("Cette application ne supporte pas l'usage de runfile");
self::die();
} }
$runfile = app::with($appClass, self::$internal_use_app_params)->getRunfile(); $runfile = app::with($appClass, self::$internal_use_app_params)->getRunfile();

View File

@ -9,6 +9,9 @@ use nur\config\ArrayConfig;
use nur\msg; use nur\msg;
use nur\os; use nur\os;
use nur\path; use nur\path;
use nur\sery\app\launcher;
use nur\sery\app\RunFile;
use nur\sery\cl;
use nur\sery\wip\app\app; use nur\sery\wip\app\app;
use nur\sery\output\log as nlog; use nur\sery\output\log as nlog;
use nur\sery\output\msg as nmsg; use nur\sery\output\msg as nmsg;
@ -365,4 +368,15 @@ abstract class Application {
} }
abstract function main(); abstract function main();
const BGLAUNCH_SCRIPT = null;
static function runfile(): RunFile {
$callerParams = app::get()->getParams();
return app::with(static::class, $callerParams)->getRunfile();
}
static function bglaunch(?array $args=null) {
launcher::launch(static::class, cl::merge([
static::BGLAUNCH_SCRIPT,
], $args));
}
} }

View File

@ -37,12 +37,13 @@ class RunFile {
} }
protected function initData(bool $withDateStart=true): array { protected function initData(bool $withDateStart=true): array {
$pid = $withDateStart? posix_getpid(): null;
$dateStart = $withDateStart? new DateTime(): null; $dateStart = $withDateStart? new DateTime(): null;
return [ return [
"name" => $this->name, "name" => $this->name,
"id" => bin2hex(random_bytes(16)), "id" => bin2hex(random_bytes(16)),
"pg_pid" => null, "pg_pid" => null,
"pid" => posix_getpid(), "pid" => $pid,
"serial" => 0, "serial" => 0,
# lock # lock
"locked" => false, "locked" => false,
@ -52,6 +53,7 @@ class RunFile {
"date_start" => $dateStart, "date_start" => $dateStart,
"date_stop" => null, "date_stop" => null,
"exitcode" => null, "exitcode" => null,
"is_done" => null,
# action # action
"action" => null, "action" => null,
"action_date_start" => null, "action_date_start" => null,
@ -72,22 +74,27 @@ class RunFile {
$file->lockWrite(); $file->lockWrite();
$data = $file->unserialize(null, false, true); $data = $file->unserialize(null, false, true);
if (!is_array($data)) { if (!is_array($data)) {
$data = $this->initData(); $data = $this->initData(false);
$file->ftruncate(); $file->ftruncate();
$file->serialize($data, false, true); $file->serialize($data, false, true);
} }
$file->ftruncate();
return [$file, $data]; return [$file, $data];
} }
protected function serialize(SharedFile $file, array $data, ?array $merge=null): void { protected function serialize(SharedFile $file, array $data, ?array $merge=null): void {
$file->ftruncate();
$file->serialize(self::merge($data, $merge), true, true); $file->serialize(self::merge($data, $merge), true, true);
} }
protected function update(callable $func): void { protected function update(callable $func): void {
/** @var SharedFile$file */
[$file, $data] = $this->willWrite(); [$file, $data] = $this->willWrite();
$merge = call_user_func($func, $data); $merge = call_user_func($func, $data);
$this->serialize($file, $data, $merge); if ($merge !== null && $merge !== false) {
$this->serialize($file, $data, $merge);
} else {
$file->cancelWrite();
}
} }
function haveWorked(int $serial, ?int &$currentSerial=null): bool { function haveWorked(int $serial, ?int &$currentSerial=null): bool {
@ -154,20 +161,20 @@ class RunFile {
}); });
} }
/** tester si l'application a déjà été démarrée */ /** tester si l'application a déjà été démarrée au moins une fois */
function wasStarted(): bool { function wasStarted(): bool {
$data = $this->read(); $data = $this->read();
return $data["date_start"] !== null; return $data["date_start"] !== null;
} }
/** tester si l'application est démarrée et non arrêtée */ /** tester si l'application est démarrée et non arrêtée */
function isStarted(): bool { function isStarted(?array &$data=null): bool {
$data = $this->read(); $data = $this->read();
return $data["date_start"] !== null && $data["date_stop"] === null; return $data["date_start"] !== null && $data["date_stop"] === null;
} }
/** /**
* vérifier si la tâche tourne et est accessible * vérifier si l'application marquée comme démarrée tourne réellement
*/ */
function isRunning(?array &$data=null): bool { function isRunning(?array &$data=null): bool {
$data = $this->read(); $data = $this->read();
@ -198,14 +205,14 @@ class RunFile {
}); });
} }
/** tester si l'application est déjà été stoppée */ /** tester si l'application est déjà été stoppée au moins une fois */
function wasStopped(): bool { function wasStopped(): bool {
$data = $this->read(); $data = $this->read();
return $data["date_stop"] !== null; return $data["date_stop"] !== null;
} }
/** tester si l'application a été démarrée puis arrêtée */ /** tester si l'application a été démarrée puis arrêtée */
function isStopped(): bool { function isStopped(?array &$data=null): bool {
$data = $this->read(); $data = $this->read();
return $data["date_start"] !== null && $data["date_stop"] !== null; return $data["date_start"] !== null && $data["date_stop"] !== null;
} }
@ -221,6 +228,24 @@ class RunFile {
}); });
} }
/**
* comme {@link self::isStopped()} mais ne renvoie true qu'une seule fois si
* $updateDone==true
*/
function isDone(?array &$data=null, bool $updateDone=true): bool {
$done = false;
$this->update(function (array $ldata) use (&$done, &$data, $updateDone) {
$data = $ldata;
if ($data["date_start"] === null || $data["date_stop"] === null || $data["is_done"]) {
return false;
}
$done = true;
if (!$updateDone) return null;
return ["is_done" => $done];
});
return $done;
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# gestion des actions # gestion des actions

View File

@ -8,7 +8,7 @@ use nur\sery\StateException;
use nur\sery\wip\app\app; use nur\sery\wip\app\app;
class launcher { class launcher {
static function launch(string $appClass, ...$args): int { static function launch(string $appClass, array $args): int {
$app = app::get(); $app = app::get();
$vendorBindir = $app->getVendorbindir(); $vendorBindir = $app->getVendorbindir();
$launch_php = "$vendorBindir/_launch.php"; $launch_php = "$vendorBindir/_launch.php";
@ -21,17 +21,20 @@ class launcher {
$cmd = new Cmd([ $cmd = new Cmd([
$launch_php, $launch_php,
"--internal-use", $tmpfile->getFile(), "--internal-use", $tmpfile->getFile(),
$appClass, ...$args, $appClass, "--", ...$args,
]); ]);
$cmd->addRedir("null"); $cmd->addRedir("null");
$cmd->passthru($exitcode); $cmd->passthru($exitcode);
# attendre un peu que la commande aie le temps de s'initialiser
sleep(1);
$tmpfile->close(); $tmpfile->close();
return $exitcode; return $exitcode;
} }
static function _start(array $args, Runfile $runfile): bool { static function _start(array $args, Runfile $runfile): bool {
if ($runfile->isLocked()) return false; if ($runfile->warnIfLocked()) return false;
$pid = pcntl_fork(); $pid = pcntl_fork();
if ($pid == -1) { if ($pid == -1) {
# parent, impossible de forker # parent, impossible de forker
@ -43,6 +46,7 @@ class launcher {
## child, fork ok ## child, fork ok
# Créer un groupe de process, pour pouvoir les tuer toutes en même temps # Créer un groupe de process, pour pouvoir les tuer toutes en même temps
$runfile->tm_startPg(); $runfile->tm_startPg();
$pid = posix_getpid();
$exitcode = -776; $exitcode = -776;
try { try {
# puis lancer la commande # puis lancer la commande
@ -50,7 +54,9 @@ class launcher {
#XXX fichier de log? #XXX fichier de log?
$cmd->addSource("/g/init.env"); $cmd->addSource("/g/init.env");
$cmd->addRedir("null"); $cmd->addRedir("null");
msg::debug("$pid: launching\n".$cmd->getCmd());
$cmd->fork_exec($exitcode); $cmd->fork_exec($exitcode);
msg::debug("$pid: exitcode=$exitcode");
return true; return true;
} finally { } finally {
$runfile->wfStopped($exitcode); $runfile->wfStopped($exitcode);

View File

@ -455,4 +455,12 @@ class Stream extends AbstractIterator implements IReader, IWriter {
function serialize($object, bool $close=true, bool $alreadyLocked=false): void { function serialize($object, bool $close=true, bool $alreadyLocked=false): void {
$this->putContents(serialize($object), $close, $alreadyLocked); $this->putContents(serialize($object), $close, $alreadyLocked);
} }
/**
* annuler une tentative d'écriture commencée avec {@link self::canWrite()}
*/
function cancelWrite(bool $close=true): void {
if ($this->useLocking) $this->unlock($close);
elseif ($close) $this->close();
}
} }