modifs.mineures sans commentaires
This commit is contained in:
parent
789642ce5f
commit
1c936caf26
|
@ -1,5 +1,5 @@
|
|||
<?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:
|
||||
# - NULIB_APP_app_params : paramètres du projet
|
||||
|
||||
|
@ -7,7 +7,10 @@ use nur\sery\os\path;
|
|||
use nur\sery\wip\app\app2;
|
||||
|
||||
if ($argc <= 1) die("invalid arguments");
|
||||
app2::init(NULIB_APP_app_params);
|
||||
app2::init([
|
||||
"projdir" => __DIR__ . '/..',
|
||||
"appcode" => \app\config\bootstrap::APPCODE,
|
||||
]);
|
||||
$app = $argv[1];
|
||||
if (class_exists($app)) {
|
||||
# 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
|
||||
# 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:
|
||||
# ce sont tous des chemins relatif au répertoire qui contient ce script
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
|||
PROJPATH=..
|
||||
|
||||
# Chemin relatif vers le lanceur PHP
|
||||
LAUNCHERPATH=_cli_simple_launcher.php
|
||||
LAUNCHERPATH=_launcher.php
|
||||
|
||||
# Chemin relatif des scripts PHP wrappés
|
||||
WRAPPEDPATH=
|
|
@ -10,6 +10,7 @@ use nur\sery\StateException;
|
|||
use nur\sery\str;
|
||||
use nur\sery\wip\app\app;
|
||||
|
||||
#XXX sera obsolète quand cli\bg_launcher sera mis en prod
|
||||
class launcher {
|
||||
/**
|
||||
* 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 {
|
||||
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() {
|
||||
|
@ -60,7 +60,7 @@ class BgLauncherApp extends Application {
|
|||
switch ($this->action) {
|
||||
case self::ACTION_START:
|
||||
$appClass::_manage_runfile(count($args), $args, $runfile);
|
||||
if ($runfile->warnIfLocked()) return;
|
||||
if ($runfile->warnIfLocked()) self::exit(app2::EC_LOCKED);
|
||||
array_splice($args, 0, 0, [
|
||||
PHP_BINARY,
|
||||
path::abspath(NULIB_APP_app_launcher),
|
||||
|
@ -70,7 +70,7 @@ class BgLauncherApp extends Application {
|
|||
break;
|
||||
case self::ACTION_STOP:
|
||||
bg_launcher::_stop($runfile);
|
||||
self::show_infos($runfile);
|
||||
self::show_infos($runfile, -1);
|
||||
break;
|
||||
case self::ACTION_INFOS:
|
||||
self::show_infos($runfile);
|
||||
|
|
|
@ -21,14 +21,14 @@ EOT,
|
|||
["-c", "--count", "args" => 1,
|
||||
"help" => "spécifier le nombre d'étapes",
|
||||
],
|
||||
["-s", "--install-signal-handler", "value" => true,
|
||||
"help" => "installer un gestionnaire de signaux",
|
||||
["-n", "--no-install-signal-handler", "value" => false,
|
||||
"help" => "ne pas installer le gestionnaire de signaux",
|
||||
],
|
||||
];
|
||||
|
||||
protected $count = 100;
|
||||
|
||||
protected bool $installSignalHandler = false;
|
||||
protected bool $installSignalHandler = true;
|
||||
|
||||
function main() {
|
||||
if ($this->installSignalHandler) app2::install_signal_handler();
|
||||
|
|
|
@ -5,6 +5,7 @@ use nur\sery\A;
|
|||
use nur\sery\cl;
|
||||
use nur\sery\file\SharedFile;
|
||||
use nur\sery\os\path;
|
||||
use nur\sery\os\sh;
|
||||
use nur\sery\output\msg;
|
||||
use nur\sery\php\time\DateTime;
|
||||
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 {
|
||||
$data = $this->file->unserialize();
|
||||
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é
|
||||
* 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\RunFile;
|
||||
use nur\sery\wip\web\content\v;
|
||||
use nur\yaml;
|
||||
|
||||
/**
|
||||
* Class Application: application de base
|
||||
|
@ -82,11 +83,21 @@ abstract class Application {
|
|||
/** @var bool faut-il installer le gestionnaire de signaux? */
|
||||
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 {
|
||||
if ($argc <= 1 || $argv[1] !== "//") return;
|
||||
array_splice($argv, 1, 1);
|
||||
$ec = 0;
|
||||
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":
|
||||
case "rl":
|
||||
|
@ -104,9 +115,17 @@ abstract class Application {
|
|||
$ec = 1;
|
||||
}
|
||||
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:
|
||||
fwrite(STDERR, "$argv[1]: unexpected command\n");
|
||||
$ec = app2::EC_BAD_COMMAND;
|
||||
$ec = self::_error("$argv[1]: unexpected command", app2::EC_BAD_COMMAND);
|
||||
}
|
||||
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 {
|
||||
$data = $runfile->read();
|
||||
$pid = $runfile->_getCid($data);
|
||||
$stopped = false;
|
||||
msg::action("term $pid");
|
||||
$timeout = 10;
|
||||
$delay = 300000;
|
||||
while (--$timeout >= 0) {
|
||||
if (!self::kill($pid, SIGTERM)) {
|
||||
msg::afailure();
|
||||
msg::action("stop $pid");
|
||||
if ($runfile->wfKill($reason)) {
|
||||
msg::asuccess();
|
||||
return true;
|
||||
} else {
|
||||
msg::afailure($reason);
|
||||
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