modifs.mineures sans commentaires
This commit is contained in:
parent
789642ce5f
commit
1c936caf26
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
# script à inclure pour implémenter _cli_simple_launcher.php
|
# script à inclure pour implémenter _launcher.php
|
||||||
# les constantes suivantes doivent être définies AVANT de chager ce script:
|
# les constantes suivantes doivent être définies AVANT de chager ce script:
|
||||||
# - NULIB_APP_app_params : paramètres du projet
|
# - NULIB_APP_app_params : paramètres du projet
|
||||||
|
|
||||||
|
@ -7,7 +7,10 @@ use nur\sery\os\path;
|
||||||
use nur\sery\wip\app\app2;
|
use nur\sery\wip\app\app2;
|
||||||
|
|
||||||
if ($argc <= 1) die("invalid arguments");
|
if ($argc <= 1) die("invalid arguments");
|
||||||
app2::init(NULIB_APP_app_params);
|
app2::init([
|
||||||
|
"projdir" => __DIR__ . '/..',
|
||||||
|
"appcode" => \app\config\bootstrap::APPCODE,
|
||||||
|
]);
|
||||||
$app = $argv[1];
|
$app = $argv[1];
|
||||||
if (class_exists($app)) {
|
if (class_exists($app)) {
|
||||||
# la configuration est celle actuellement chargée
|
# la configuration est celle actuellement chargée
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/php
|
||||||
|
<?php
|
||||||
|
require __DIR__.'/../vendor/autoload.php';
|
||||||
|
# Lancer une application en tâche de fond
|
||||||
|
|
||||||
|
# TODO Faire une copie de ce script dans un répertoire de l'application web
|
||||||
|
# (par défaut c'est le répertoire bin/) et modifier les paramètres si nécessaire
|
||||||
|
|
||||||
|
use nur\sery\tools\BgLauncherApp;
|
||||||
|
use nur\sery\wip\app\app2;
|
||||||
|
|
||||||
|
# chemin vers le lanceur PHP
|
||||||
|
const NULIB_APP_app_launcher = __DIR__.'/../_cli/_launcher.php';
|
||||||
|
|
||||||
|
app2::init([
|
||||||
|
"projdir" => __DIR__ . '/..',
|
||||||
|
"appcode" => \app\config\bootstrap::APPCODE,
|
||||||
|
]);
|
||||||
|
BgLauncherApp::run();
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||||
# s'assurer que le script PHP est lancé avec l'utilisateur www-data
|
# s'assurer que le script PHP est lancé avec l'utilisateur www-data
|
||||||
|
|
||||||
# Faire une copie de ce script dans un répertoire de l'application web
|
# TODO Faire une copie de ce script dans un répertoire de l'application web
|
||||||
# (par défaut c'est le répertoire _cli/) et paramétrer les variables suivantes:
|
# (par défaut c'est le répertoire _cli/) et paramétrer les variables suivantes:
|
||||||
# ce sont tous des chemins relatif au répertoire qui contient ce script
|
# ce sont tous des chemins relatif au répertoire qui contient ce script
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
PROJPATH=..
|
PROJPATH=..
|
||||||
|
|
||||||
# Chemin relatif vers le lanceur PHP
|
# Chemin relatif vers le lanceur PHP
|
||||||
LAUNCHERPATH=_cli_simple_launcher.php
|
LAUNCHERPATH=_launcher.php
|
||||||
|
|
||||||
# Chemin relatif des scripts PHP wrappés
|
# Chemin relatif des scripts PHP wrappés
|
||||||
WRAPPEDPATH=
|
WRAPPEDPATH=
|
|
@ -10,6 +10,7 @@ use nur\sery\StateException;
|
||||||
use nur\sery\str;
|
use nur\sery\str;
|
||||||
use nur\sery\wip\app\app;
|
use nur\sery\wip\app\app;
|
||||||
|
|
||||||
|
#XXX sera obsolète quand cli\bg_launcher sera mis en prod
|
||||||
class launcher {
|
class launcher {
|
||||||
/**
|
/**
|
||||||
* transformer une liste d'argument de la forme
|
* transformer une liste d'argument de la forme
|
||||||
|
|
|
@ -36,7 +36,7 @@ class BgLauncherApp extends Application {
|
||||||
|
|
||||||
static function show_infos(RunFile $runfile, ?int $level=null): void {
|
static function show_infos(RunFile $runfile, ?int $level=null): void {
|
||||||
msg::print($runfile->getDesc(), $level);
|
msg::print($runfile->getDesc(), $level);
|
||||||
msg::print(yaml::with(["data" => $runfile->read()]), -1);
|
msg::print(yaml::with(["data" => $runfile->read()]), ($level ?? 0) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
@ -60,7 +60,7 @@ class BgLauncherApp extends Application {
|
||||||
switch ($this->action) {
|
switch ($this->action) {
|
||||||
case self::ACTION_START:
|
case self::ACTION_START:
|
||||||
$appClass::_manage_runfile(count($args), $args, $runfile);
|
$appClass::_manage_runfile(count($args), $args, $runfile);
|
||||||
if ($runfile->warnIfLocked()) return;
|
if ($runfile->warnIfLocked()) self::exit(app2::EC_LOCKED);
|
||||||
array_splice($args, 0, 0, [
|
array_splice($args, 0, 0, [
|
||||||
PHP_BINARY,
|
PHP_BINARY,
|
||||||
path::abspath(NULIB_APP_app_launcher),
|
path::abspath(NULIB_APP_app_launcher),
|
||||||
|
@ -70,7 +70,7 @@ class BgLauncherApp extends Application {
|
||||||
break;
|
break;
|
||||||
case self::ACTION_STOP:
|
case self::ACTION_STOP:
|
||||||
bg_launcher::_stop($runfile);
|
bg_launcher::_stop($runfile);
|
||||||
self::show_infos($runfile);
|
self::show_infos($runfile, -1);
|
||||||
break;
|
break;
|
||||||
case self::ACTION_INFOS:
|
case self::ACTION_INFOS:
|
||||||
self::show_infos($runfile);
|
self::show_infos($runfile);
|
||||||
|
|
|
@ -21,14 +21,14 @@ EOT,
|
||||||
["-c", "--count", "args" => 1,
|
["-c", "--count", "args" => 1,
|
||||||
"help" => "spécifier le nombre d'étapes",
|
"help" => "spécifier le nombre d'étapes",
|
||||||
],
|
],
|
||||||
["-s", "--install-signal-handler", "value" => true,
|
["-n", "--no-install-signal-handler", "value" => false,
|
||||||
"help" => "installer un gestionnaire de signaux",
|
"help" => "ne pas installer le gestionnaire de signaux",
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $count = 100;
|
protected $count = 100;
|
||||||
|
|
||||||
protected bool $installSignalHandler = false;
|
protected bool $installSignalHandler = true;
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
if ($this->installSignalHandler) app2::install_signal_handler();
|
if ($this->installSignalHandler) app2::install_signal_handler();
|
||||||
|
|
|
@ -5,6 +5,7 @@ use nur\sery\A;
|
||||||
use nur\sery\cl;
|
use nur\sery\cl;
|
||||||
use nur\sery\file\SharedFile;
|
use nur\sery\file\SharedFile;
|
||||||
use nur\sery\os\path;
|
use nur\sery\os\path;
|
||||||
|
use nur\sery\os\sh;
|
||||||
use nur\sery\output\msg;
|
use nur\sery\output\msg;
|
||||||
use nur\sery\php\time\DateTime;
|
use nur\sery\php\time\DateTime;
|
||||||
use nur\sery\php\time\Elapsed;
|
use nur\sery\php\time\Elapsed;
|
||||||
|
@ -70,6 +71,16 @@ class RunFile {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset(bool $delete=false) {
|
||||||
|
$file = $this->file;
|
||||||
|
if ($delete) {
|
||||||
|
$file->close();
|
||||||
|
unlink($file->getFile());
|
||||||
|
} else {
|
||||||
|
$file->ftruncate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function read(): array {
|
function read(): array {
|
||||||
$data = $this->file->unserialize();
|
$data = $this->file->unserialize();
|
||||||
if (!is_array($data)) $data = $this->initData();
|
if (!is_array($data)) $data = $this->initData();
|
||||||
|
@ -274,6 +285,59 @@ class RunFile {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function kill(int $pid, int $signal, ?string &$reason=null): bool {
|
||||||
|
if (!posix_kill($pid, $signal)) {
|
||||||
|
switch (posix_get_last_error()) {
|
||||||
|
case PCNTL_ESRCH:
|
||||||
|
$reason = "process inexistant";
|
||||||
|
break;
|
||||||
|
case PCNTL_EPERM:
|
||||||
|
$reason = "process non accessible";
|
||||||
|
break;
|
||||||
|
case PCNTL_EINVAL:
|
||||||
|
$reason = "signal invalide";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wfKill(?string &$reason=null): bool {
|
||||||
|
$data = $this->read();
|
||||||
|
$pid = $this->_getCid($data);
|
||||||
|
$stopped = false;
|
||||||
|
$timeout = 10;
|
||||||
|
$delay = 300000;
|
||||||
|
while (--$timeout >= 0) {
|
||||||
|
if (!self::kill($pid, SIGTERM, $reason)) return false;
|
||||||
|
usleep($delay);
|
||||||
|
$delay = 1000000; // attendre 1 seconde à partir de la deuxième fois
|
||||||
|
if (!$this->_isRunning($data)) {
|
||||||
|
$stopped = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$stopped) {
|
||||||
|
$timeout = 3;
|
||||||
|
$delay = 300000;
|
||||||
|
while (--$timeout >= 0) {
|
||||||
|
if (!self::kill($pid, SIGKILL, $reason)) return false;
|
||||||
|
usleep($delay);
|
||||||
|
$delay = 1000000; // attendre 1 seconde à partir de la deuxième fois
|
||||||
|
if (!$this->_isRunning($data)) {
|
||||||
|
$stopped = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($stopped) {
|
||||||
|
sh::_waitpid($pid, $exitcode);
|
||||||
|
$this->wfReaped($exitcode);
|
||||||
|
}
|
||||||
|
return $stopped;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vérifier si on est dans le cas où la tâche devrait tourner mais en réalité
|
* vérifier si on est dans le cas où la tâche devrait tourner mais en réalité
|
||||||
* ce n'est pas le cas
|
* ce n'est pas le cas
|
||||||
|
|
|
@ -14,6 +14,7 @@ use nur\sery\ValueException;
|
||||||
use nur\sery\wip\app\app2;
|
use nur\sery\wip\app\app2;
|
||||||
use nur\sery\wip\app\RunFile;
|
use nur\sery\wip\app\RunFile;
|
||||||
use nur\sery\wip\web\content\v;
|
use nur\sery\wip\web\content\v;
|
||||||
|
use nur\yaml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Application: application de base
|
* Class Application: application de base
|
||||||
|
@ -82,11 +83,21 @@ abstract class Application {
|
||||||
/** @var bool faut-il installer le gestionnaire de signaux? */
|
/** @var bool faut-il installer le gestionnaire de signaux? */
|
||||||
const INSTALL_SIGNAL_HANDLER = false;
|
const INSTALL_SIGNAL_HANDLER = false;
|
||||||
|
|
||||||
|
private static function _error(string $message, int $ec=1): int {
|
||||||
|
fwrite(STDERR, "ERROR: $message\n");
|
||||||
|
return $ec;
|
||||||
|
}
|
||||||
|
|
||||||
static function _manage_runfile(int $argc, array $argv, RunFile $runfile): void {
|
static function _manage_runfile(int $argc, array $argv, RunFile $runfile): void {
|
||||||
if ($argc <= 1 || $argv[1] !== "//") return;
|
if ($argc <= 1 || $argv[1] !== "//") return;
|
||||||
array_splice($argv, 1, 1);
|
array_splice($argv, 1, 1);
|
||||||
$ec = 0;
|
$ec = 0;
|
||||||
switch ($argv[1] ?? "infos") {
|
switch ($argv[1] ?? "infos") {
|
||||||
|
case "kill":
|
||||||
|
case "k":
|
||||||
|
if ($runfile->isRunning()) $runfile->wfKill();
|
||||||
|
else $ec = self::_error("not running");
|
||||||
|
break;
|
||||||
case "release-lock":
|
case "release-lock":
|
||||||
case "release":
|
case "release":
|
||||||
case "rl":
|
case "rl":
|
||||||
|
@ -104,9 +115,17 @@ abstract class Application {
|
||||||
$ec = 1;
|
$ec = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "dump":
|
||||||
|
case "d":
|
||||||
|
yaml::dump($runfile->read());
|
||||||
|
break;
|
||||||
|
case "reset":
|
||||||
|
case "z":
|
||||||
|
if (!$runfile->isRunning()) $runfile->reset();
|
||||||
|
else $ec = self::_error("cannot reset while running");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fwrite(STDERR, "$argv[1]: unexpected command\n");
|
$ec = self::_error("$argv[1]: unexpected command", app2::EC_BAD_COMMAND);
|
||||||
$ec = app2::EC_BAD_COMMAND;
|
|
||||||
}
|
}
|
||||||
exit($ec);
|
exit($ec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,66 +32,16 @@ class bg_launcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function kill(int $pid, int $signal): bool {
|
|
||||||
if (!posix_kill($pid, $signal)) {
|
|
||||||
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 false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static function _stop(Runfile $runfile): bool {
|
static function _stop(Runfile $runfile): bool {
|
||||||
$data = $runfile->read();
|
$data = $runfile->read();
|
||||||
$pid = $runfile->_getCid($data);
|
$pid = $runfile->_getCid($data);
|
||||||
$stopped = false;
|
msg::action("stop $pid");
|
||||||
msg::action("term $pid");
|
if ($runfile->wfKill($reason)) {
|
||||||
$timeout = 10;
|
msg::asuccess();
|
||||||
$delay = 300000;
|
return true;
|
||||||
while (--$timeout >= 0) {
|
} else {
|
||||||
if (!self::kill($pid, SIGTERM)) {
|
msg::afailure($reason);
|
||||||
msg::afailure();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
usleep($delay);
|
|
||||||
$delay = 1000000; // attendre 1 seconde à partir de la deuxième fois
|
|
||||||
if (!$runfile->_isRunning($data)) {
|
|
||||||
msg::asuccess();
|
|
||||||
$stopped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$stopped) {
|
|
||||||
msg::action("kill $pid");
|
|
||||||
$timeout = 3;
|
|
||||||
$delay = 300000;
|
|
||||||
while (--$timeout >= 0) {
|
|
||||||
if (!self::kill($pid, SIGKILL)) {
|
|
||||||
msg::afailure();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
usleep($delay);
|
|
||||||
$delay = 1000000; // attendre 1 seconde à partir de la deuxième fois
|
|
||||||
if (!$runfile->_isRunning($data)) {
|
|
||||||
msg::asuccess();
|
|
||||||
$stopped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($stopped) {
|
|
||||||
sh::_waitpid($pid, $exitcode);
|
|
||||||
$runfile->wfReaped($exitcode);
|
|
||||||
}
|
|
||||||
return $stopped;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue