modifs.mineures sans commentaires
This commit is contained in:
parent
e9ab61b154
commit
dca04418b7
|
@ -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();
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
if ($merge !== null && $merge !== false) {
|
||||||
$this->serialize($file, $data, $merge);
|
$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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue