This commit is contained in:
jygaulier
2013-10-14 16:58:32 +02:00
parent cafb588e8d
commit f32d561c98
2 changed files with 57 additions and 25 deletions

View File

@@ -34,11 +34,15 @@ class task_Scheduler
private $method; private $method;
private $dependencyContainer; private $dependencyContainer;
private $schedstatus;
public function __construct(Application $application, Logger $logger) public function __construct(Application $application, Logger $logger)
{ {
declare(ticks = 1); declare(ticks = 1);
$this->dependencyContainer = $application; $this->dependencyContainer = $application;
$this->logger = $logger; $this->logger = $logger;
$this->schedstatus = '';
} }
protected function log($message) protected function log($message)
@@ -54,10 +58,21 @@ class task_Scheduler
*/ */
public function sigHandler($signal) public function sigHandler($signal)
{ {
switch ($signal) {
case SIGCHLD:
$status = null; $status = null;
$pid = pcntl_wait($status); $pid = pcntl_wait($status);
$exitstatus = pcntl_wexitstatus($status); $exitstatus = pcntl_wexitstatus($status);
$this->log(sprintf("sigchild %s received from pid=%s, status=%s, exitstatus=%s\n", $signal, $pid, var_export($status, true), $exitstatus)); $this->log(sprintf("SIGCHLD (%s) received from pid=%s, status=%s, exitstatus=%s", $signal, $pid, var_export($status, true), $exitstatus));
break;
case SIGINT: // ctrl C
$this->log(sprintf("SIGINT (%s) Ctrl-C received, schedstatus='tostop'", $signal));
$this->schedstatus = 'tostop';
break;
case SIGTERM:
$this->log(sprintf("SIGTERM (%s) received but ignored, http timeout ?", $signal));
break;
}
} }
public function run() public function run()
@@ -87,6 +102,8 @@ class task_Scheduler
// pcntl_signal(SIGCHLD, SIG_IGN); // no zombies but no returnValue // pcntl_signal(SIGCHLD, SIG_IGN); // no zombies but no returnValue
// pcntl_signal(SIGCHLD, SIG_DFL); // with "declare(ticks=1)" returnValue ok but zombies // pcntl_signal(SIGCHLD, SIG_DFL); // with "declare(ticks=1)" returnValue ok but zombies
pcntl_signal(SIGCHLD, array($this, 'sigHandler')); // ok pcntl_signal(SIGCHLD, array($this, 'sigHandler')); // ok
pcntl_signal(SIGINT, array($this, 'sigHandler'));
pcntl_signal(SIGTERM, array($this, 'sigHandler'));
$this->method = self::METHOD_FORK; $this->method = self::METHOD_FORK;
} }
@@ -147,11 +164,11 @@ class task_Scheduler
} }
} }
$schedstatus = 'started'; $this->schedstatus = 'started';
$runningtask = 0; $runningtask = 0;
$connwaslost = false; $connwaslost = false;
while ($schedstatus == 'started' || $runningtask > 0) { while ($this->schedstatus == 'started' || $runningtask > 0) {
while (1) { while (1) {
try { try {
assert(is_object($conn)); assert(is_object($conn));
@@ -189,7 +206,8 @@ class task_Scheduler
$connwaslost = false; $connwaslost = false;
} }
$schedstatus = ''; if ($this->schedstatus == "started") {
$this->schedstatus = '';
$row = NULL; $row = NULL;
try { try {
$sql = "SELECT schedstatus FROM sitepreff"; $sql = "SELECT schedstatus FROM sitepreff";
@@ -202,10 +220,11 @@ class task_Scheduler
} }
if ($row) { if ($row) {
$schedstatus = $row["schedstatus"]; $this->schedstatus = $row["schedstatus"];
}
} }
if ($schedstatus == 'tostop') { if ($this->schedstatus == 'tostop') {
$sql = 'UPDATE sitepreff SET schedstatus = "stopping"'; $sql = 'UPDATE sitepreff SET schedstatus = "stopping"';
$stmt = $conn->prepare($sql); $stmt = $conn->prepare($sql);
$stmt->execute(); $stmt->execute();
@@ -327,7 +346,7 @@ class task_Scheduler
} }
} }
if ($schedstatus == 'started') { if ($this->schedstatus == 'started') {
$taskPoll[$tkey]["task"]->setState(task_abstract::STATE_TOSTART); $taskPoll[$tkey]["task"]->setState(task_abstract::STATE_TOSTART);
} }
// trick to start the task immediatly : DON'T break if ending with 'tostart' // trick to start the task immediatly : DON'T break if ending with 'tostart'
@@ -338,7 +357,7 @@ class task_Scheduler
case task_abstract::STATE_TOSTART: case task_abstract::STATE_TOSTART:
// if scheduler is 'tostop', don't launch a new task ! // if scheduler is 'tostop', don't launch a new task !
if ($schedstatus != 'started') { if ($this->schedstatus != 'started') {
break; break;
} }
@@ -567,9 +586,15 @@ class task_Scheduler
break; break;
} }
} }
if(function_exists('pcntl_sigprocmask')) {
for ($i = 0; $i < $sleeptime; $i ++) { @pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
}
sleep(1); sleep(1);
for ($i = 0; $this->schedstatus=='started' && $i < $sleeptime; $i++) {
sleep(1);
}
if(function_exists('pcntl_sigprocmask')) {
@pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
} }
} }

View File

@@ -161,6 +161,13 @@ class task_manager
if (!in_array($status, $av_status)) if (!in_array($status, $av_status))
throw new Exception(sprintf('unknown status `%s` ', $status)); throw new Exception(sprintf('unknown status `%s` ', $status));
if ($status == self::STATE_TOSTOP && function_exists('posix_kill')) {
$gs = $this->getSchedulerState();
if ($gs['pid'] !== NULL) {
@posix_kill($gs['pid'], 2); // 2 = SIGINT
}
}
$sql = "UPDATE sitepreff SET schedstatus = :schedstatus, schedqtime=NOW()"; $sql = "UPDATE sitepreff SET schedstatus = :schedstatus, schedqtime=NOW()";
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql); $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':schedstatus' => $status)); $stmt->execute(array(':schedstatus' => $status));