This commit is contained in:
jygaulier
2012-01-19 21:01:03 +01:00
parent e5828f06bb
commit 5a5f86a97b
7 changed files with 1079 additions and 653 deletions

View File

@@ -25,11 +25,16 @@ use Symfony\Component\Console\Command\Command;
class module_console_taskrun extends Command class module_console_taskrun extends Command
{ {
private $task;
private $shedulerPID;
public function __construct($name = null) public function __construct($name = null)
{ {
parent::__construct($name); parent::__construct($name);
$this->task = NULL;
$this->shedulerPID = NULL;
$this->addArgument('task_id', InputArgument::REQUIRED, 'The task_id to run'); $this->addArgument('task_id', InputArgument::REQUIRED, 'The task_id to run');
$this->addOption( $this->addOption(
'runner' 'runner'
@@ -59,16 +64,51 @@ class module_console_taskrun extends Command
$appbox = appbox::get_instance(); $appbox = appbox::get_instance();
$task_manager = new task_manager($appbox); $task_manager = new task_manager($appbox);
$task = $task_manager->get_task($task_id); $this->task = $task_manager->get_task($task_id);
$runner = task_abstract::RUNNER_SCHEDULER;
if($input->getOption('runner') === task_abstract::RUNNER_MANUAL) if($input->getOption('runner') === task_abstract::RUNNER_MANUAL)
{
$runner = task_abstract::RUNNER_MANUAL; $runner = task_abstract::RUNNER_MANUAL;
}
else
{
$runner = task_abstract::RUNNER_SCHEDULER;
$registry = $appbox->get_registry();
$schedFile = $registry->get('GV_RootPath') . 'tmp/locks/scheduler.lock';
if(file_exists($schedFile))
$this->shedulerPID = (int) (trim(file_get_contents($schedFile)));
}
$task->run($runner); register_tick_function(array($this, 'tick_handler'), true);
declare(ticks=1);
$this->task->run($runner);
printf("TASK QUIT\n");
return $this; return $this;
} }
public function tick_handler()
{
static $start = FALSE;
if($start === FALSE)
$start = time();
if(time() - $start > 0)
{
if($this->shedulerPID)
{
if(!posix_kill($this->shedulerPID, 0))
{
if(method_exists($this->task, 'signal'))
$this->task->signal('SIGNAL_SCHEDULER_DIED');
else
$this->task->set_status(task_abstract::STATUS_TOSTOP);
}
}
$start = time();
}
}
} }

View File

@@ -21,25 +21,31 @@ class task_Scheduler
{ {
const TASKDELAYTOQUIT = 60; const TASKDELAYTOQUIT = 60;
// how to schedule tasks (choose in 'run' method)
const METHOD_FORK = 'METHOD_FORK';
const METHOD_PROC_OPEN = 'METHOD_PROC_OPEN';
private $method;
protected $output; protected $output;
protected function log($message) protected function log($message)
{ {
if ($this->output instanceof OutputInterface)
{
$this->output->writeln($message);
}
$registry = registry::get_instance(); $registry = registry::get_instance();
$logdir = $registry->get('GV_RootPath') . 'logs/'; $logdir = $registry->get('GV_RootPath') . 'logs/';
logs::rotate($logdir . "scheduler.log"); logs::rotate($logdir . "scheduler.log");
$date_obj = new DateTime(); $date_obj = new DateTime();
$message = sprintf("%s %s \n", $date_obj->format(DATE_ATOM), $message); $message = sprintf("%s\t%s", $date_obj->format(DATE_ATOM), $message);
file_put_contents($logdir . "scheduler.log", $message, FILE_APPEND);
if($this->output instanceof OutputInterface)
{
$this->output->writeln($message);
}
// else
{
file_put_contents($logdir . "scheduler.log", $message."\n", FILE_APPEND);
}
return $this; return $this;
} }
@@ -52,6 +58,8 @@ class task_Scheduler
public function run(OutputInterface $output = null, $log_tasks = true) public function run(OutputInterface $output = null, $log_tasks = true)
{ {
$this->method = self::METHOD_FORK;
require_once dirname(__FILE__) . '/../../bootstrap.php'; require_once dirname(__FILE__) . '/../../bootstrap.php';
$this->output = $output; $this->output = $output;
$appbox = appbox::get_instance(); $appbox = appbox::get_instance();
@@ -63,8 +71,9 @@ class task_Scheduler
for($try = 0; true; $try++) for($try = 0; true; $try++)
{ {
$schedlock = fopen(($lockfile = ($lockdir . 'scheduler.lock')), 'a+'); if(($schedlock = fopen(($lockfile = ($lockdir . 'scheduler.lock')), 'a+')))
if (flock($schedlock, LOCK_EX | LOCK_NB) != true) {
if(flock($schedlock, LOCK_EX | LOCK_NB) === FALSE)
{ {
$this->log(sprintf("failed to lock '%s' (try=%s/4)", $lockfile, $try)); $this->log(sprintf("failed to lock '%s' (try=%s/4)", $lockfile, $try));
if($try == 4) if($try == 4)
@@ -81,46 +90,52 @@ class task_Scheduler
} }
else else
{ {
// locked
ftruncate($schedlock, 0); ftruncate($schedlock, 0);
fwrite($schedlock, '' . getmypid()); fwrite($schedlock, '' . getmypid());
fflush($schedlock); fflush($schedlock);
break; break;
} }
} }
}
$this->log(sprintf("running scheduler with method %s", $this->method));
if($this->method == self::METHOD_FORK)
pcntl_signal(SIGCHLD, SIG_IGN);
$logdir = $registry->get('GV_RootPath') . 'logs/'; $logdir = $registry->get('GV_RootPath') . 'logs/';
$conn = self::get_connection(); $conn = self::get_connection();
$ttask = array(); $taskPoll = array(); // the poll of tasks
$sleeptime = 3; $sleeptime = 3;
$sql = "UPDATE sitepreff SET schedstatus='started', schedpid = :pid"; $sql = "UPDATE sitepreff SET schedstatus='started'";
$stmt = $conn->prepare($sql); $conn->exec($sql);
$stmt->execute(array(':pid' => getmypid()));
$stmt->closeCursor();
$task_manager = new task_manager($appbox); $task_manager = new task_manager($appbox);
$tlist = array(); // set every 'auto-start' task to start
foreach($task_manager->get_tasks() as $task) foreach($task_manager->get_tasks() as $task)
{ {
if (!$task->is_active()) if($task->is_active())
{ {
continue;
}
$tid = $task->get_task_id(); $tid = $task->get_task_id();
if (!$task->is_running()) if(!$task->get_pid())
{ {
/* @var $task task_abstract */ /* @var $task task_abstract */
$task->reset_crash_counter(); $task->reset_crash_counter();
$task->set_status(task_abstract::STATUS_TOSTART); $task->set_status(task_abstract::STATUS_TOSTART);
} }
} }
}
$tlist = array();
$schedstatus = 'started'; $schedstatus = 'started';
@@ -186,19 +201,9 @@ class task_Scheduler
logs::rotate($logdir . "scheduler.error.log"); logs::rotate($logdir . "scheduler.error.log");
/** // initialy, all tasks are supposed to be removed from the poll
* potentially, all tasks are supposed to be removed foreach($taskPoll as $tkey => $task)
*/ $taskPoll[$tkey]["todel"] = true;
foreach ($ttask as $tkey => $tv)
{
$ttask[$tkey]["todel"] = true;
}
$sql = "SELECT * FROM task2";
$stmt = $conn->prepare($sql);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
foreach($task_manager->get_tasks(true) as $task) foreach($task_manager->get_tasks(true) as $task)
{ {
@@ -207,8 +212,9 @@ class task_Scheduler
logs::rotate($logdir . "task_$tkey.log"); logs::rotate($logdir . "task_$tkey.log");
logs::rotate($logdir . "task_$tkey.error.log"); logs::rotate($logdir . "task_$tkey.error.log");
if (!isset($ttask[$tkey])) if(!isset($taskPoll[$tkey]))
{ {
// the task is not in the poll, add it
$phpcli = $registry->get('GV_cli'); $phpcli = $registry->get('GV_cli');
switch($system) switch($system)
@@ -217,56 +223,64 @@ class task_Scheduler
case "DARWIN": case "DARWIN":
case "WINDOWS": case "WINDOWS":
case "LINUX": case "LINUX":
$cmd = $phpcli . ' -f ' $cmd = $phpcli;
. $registry->get('GV_RootPath') $args = array('-f', $registry->get('GV_RootPath') . 'bin/console', 'task:run', $task->get_task_id(), '--runner=scheduler');
. "bin/console task:run "
. $task->get_task_id()
. " --runner=scheduler ";
break; break;
} }
$ttask[$tkey] = array( $taskPoll[$tkey] = array(
"task" => $task, "task" => $task,
"current_status" => $task->get_status(), "current_status" => $task->get_status(),
"process" => null,
"cmd" => $cmd, "cmd" => $cmd,
"killat" => null, "args" => $args,
"pipes" => null "killat" => null
); );
if($this->method == self::METHOD_PROC_OPEN)
{
$taskPoll[$tkey]['process'] = NULL;
$taskPoll[$tkey]['pipes'] = NULL;
}
$this->log( $this->log(
sprintf( sprintf(
"new Task %s, status=%s" "new Task %s, status=%s"
, $ttask[$tkey]["task"]->get_task_id() , $taskPoll[$tkey]["task"]->get_task_id()
, $task->get_status() , $task->get_status()
) )
); );
} }
else else
{ {
if ($ttask[$tkey]["current_status"] != $task->get_status()) // the task is already in the poll, update its status
if($taskPoll[$tkey]["current_status"] != $task->get_status())
{ {
$this->log( $this->log(
sprintf( sprintf(
"Task %s, oldstatus=%s, newstatus=%s" "Task %s, oldstatus=%s, newstatus=%s"
, $ttask[$tkey]["task"]->get_task_id() , $taskPoll[$tkey]["task"]->get_task_id()
, $ttask[$tkey]["current_status"] , $taskPoll[$tkey]["current_status"]
, $task->get_status() , $task->get_status()
) )
); );
$ttask[$tkey]["current_status"] = $task->get_status(); $taskPoll[$tkey]["current_status"] = $task->get_status();
}
// update the whole task object
unset($taskPoll[$tkey]["task"]);
$taskPoll[$tkey]["task"] = $task;
} }
$ttask[$tkey]["task"] = $task; unset($task);
}
$ttask[$tkey]["todel"] = false; $taskPoll[$tkey]["todel"] = false; // this task exists, do not remove from poll
} }
foreach ($ttask as $tkey => $tv) // remove not-existing task from poll
foreach($taskPoll as $tkey => $task)
{ {
if ($tv["todel"]) if($task["todel"])
{ {
$this->log(sprintf("Task %s deleted", $ttask[$tkey]["task"]->get_task_id())); $this->log(sprintf("Task %s deleted", $taskPoll[$tkey]["task"]->get_task_id()));
unset($ttask[$tkey]); unset($taskPoll[$tkey]);
} }
} }
@@ -276,51 +290,51 @@ class task_Scheduler
*/ */
$runningtask = 0; $runningtask = 0;
$common_status = array( foreach($taskPoll as $tkey => $tv)
task_abstract::STATUS_STARTED
, task_abstract::RETURNSTATUS_STOPPED
);
foreach ($ttask as $tkey => $tv)
{ {
if (!in_array($ttask[$tkey]["task"]->get_status(), $common_status)) switch($tv['task']->get_status())
{
$this->log(
sprintf(
'task %s has status %s'
, $ttask[$tkey]["task"]->get_task_id()
, $ttask[$tkey]["task"]->get_status()
)
);
}
switch ($ttask[$tkey]["task"]->get_status())
{ {
default: default:
$this->log( $this->log(sprintf('Unknow status `%s`', $tv['task']->get_status()));
sprintf(
'Unknow status `%s`'
, $ttask[$tkey]["task"]->get_status()
)
);
break; break;
case task_abstract::RETURNSTATUS_TORESTART:
@fclose($ttask[$tkey]["pipes"][1]);
@fclose($ttask[$tkey]["pipes"][2]);
@proc_close($ttask[$tkey]["process"]);
$ttask[$tkey]["process"] = null; case task_abstract::RETURNSTATUS_TORESTART:
if(!$taskPoll[$tkey]['task']->get_pid())
{
if($this->method == self::METHOD_PROC_OPEN)
{
@fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($taskPoll[$tkey]["process"]);
$taskPoll[$tkey]["process"] = null;
}
if($schedstatus == 'started') if($schedstatus == 'started')
{ {
$ttask[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART); $taskPoll[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART);
} }
// trick to start the task immediatly : DON'T break if ending with 'tostart'
// so it will continue with 'tostart' case !
}
else
{
break; break;
}
case task_abstract::STATUS_TOSTART: case task_abstract::STATUS_TOSTART:
$ttask[$tkey]["killat"] = NULL; // if scheduler is 'tostop', don't launch a new task !
if ($schedstatus == 'started' && !$ttask[$tkey]["process"]) if($schedstatus != 'started')
break;
$taskPoll[$tkey]["killat"] = NULL;
if($this->method == self::METHOD_PROC_OPEN)
{
if(!$taskPoll[$tkey]["process"])
{ {
$descriptors = array( $descriptors = array(
1 => array("pipe", "w") 1 => array("pipe", "w"),
, 2 => array("pipe", "w") 2 => array("pipe", "w")
); );
if($log_tasks === true) if($log_tasks === true)
@@ -337,76 +351,109 @@ class task_Scheduler
); );
} }
$ttask[$tkey]["process"] = proc_open( $taskPoll[$tkey]["process"] = proc_open(
$ttask[$tkey]["cmd"] $taskPoll[$tkey]["cmd"] . ' ' . implode(' ', $taskPoll[$tkey]["args"])
, $descriptors , $descriptors
, $ttask[$tkey]["pipes"] , $taskPoll[$tkey]["pipes"]
, $registry->get('GV_RootPath') . "bin/" , $registry->get('GV_RootPath') . "bin/"
, null , null
, array('bypass_shell' => true) , array('bypass_shell' => true)
); );
if (is_resource($ttask[$tkey]["process"])) if(is_resource($taskPoll[$tkey]["process"]))
{ {
// proc_status['pid'] if the pid of the sh !!! sleep(2); // let the process lock and write it's pid
// $proc_status = proc_get_status($ttask[$tkey]["process"]);
// if ($proc_status['running'])
// $ttask[$tkey]['task']->set_pid($proc_status['pid']);
} }
if ($ttask[$tkey]['task']->get_pid() !== null) if(is_resource($taskPoll[$tkey]["process"]) && $taskPoll[$tkey]['task']->get_pid() !== null)
{ {
$this->log( $this->log(
sprintf( sprintf(
"Task %s '%s' started (pid=%s)" "Task %s '%s' started (pid=%s)"
, $ttask[$tkey]['task']->get_task_id() , $taskPoll[$tkey]['task']->get_task_id()
, $ttask[$tkey]["cmd"] , $taskPoll[$tkey]["cmd"]
, $ttask[$tkey]['task']->get_pid() , $taskPoll[$tkey]['task']->get_pid()
) )
); );
$runningtask++; $runningtask++;
} }
else else
{ {
$ttask[$tkey]["task"]->increment_crash_counter(); $taskPoll[$tkey]["task"]->increment_crash_counter();
@fclose($ttask[$tkey]["pipes"][1]); @fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($ttask[$tkey]["pipes"][2]); @fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($ttask[$tkey]["process"]); @proc_close($taskPoll[$tkey]["process"]);
$ttask[$tkey]["process"] = null; $taskPoll[$tkey]["process"] = null;
$this->log( $this->log(
sprintf( sprintf(
"Task %s '%s' failed to start %d times" "Task %s '%s' failed to start %d times"
, $ttask[$tkey]["task"]->get_task_id() , $taskPoll[$tkey]["task"]->get_task_id()
, $ttask[$tkey]["cmd"] , $taskPoll[$tkey]["cmd"]
, $ttask[$tkey]["task"]->get_crash_counter() , $taskPoll[$tkey]["task"]->get_crash_counter()
) )
); );
if ($ttask[$tkey]["task"]->get_crash_counter() > 5) if($taskPoll[$tkey]["task"]->get_crash_counter() > 5)
$taskPoll[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED);
else
$taskPoll[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART);
}
}
}
elseif($this->method == self::METHOD_FORK)
{ {
$ttask[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED); // printf("forking pid %d\n", getmypid());
$pid = pcntl_fork();
if($pid == -1)
{
die("failed to fork");
}
elseif($pid == 0)
{
// child
// printf("hello i am child pid=%d\n", getmypid());
// printf("%s %s \n", $taskPoll[$tkey]["cmd"], implode(' ', $taskPoll[$tkey]["args"]));
// ;
umask(0);
openlog('MyLog', LOG_PID | LOG_PERROR, LOG_LOCAL0);
if(posix_setsid() < 0)
die("Forked process could not detach from terminal\n");
//chdir(dirname(__FILE__));
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
$fdIN = fopen('/dev/null', 'r');
$fdOUT = fopen($logdir . "task_$tkey.log", 'a+');
$fdERR = fopen($logdir . "task_$tkey.error.log", 'a+');
pcntl_exec($taskPoll[$tkey]["cmd"], $taskPoll[$tkey]["args"]);
sleep(2);
} }
else else
{ {
$ttask[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART); // parent
} // printf("hello i am parent pid=%d\n", getmypid());
} }
} }
break; break;
case task_abstract::STATUS_STARTED: case task_abstract::STATUS_STARTED:
$crashed = false; $crashed = false;
/** // If no process, the task is probably manually ran
* If no process, the task is probably manually ran
*/ if($this->method == self::METHOD_PROC_OPEN)
if ($ttask[$tkey]["process"])
{ {
$ttask[$tkey]["killat"] = NULL; if($taskPoll[$tkey]["process"])
if (is_resource($ttask[$tkey]["process"]))
{ {
$proc_status = proc_get_status($ttask[$tkey]["process"]); $taskPoll[$tkey]["killat"] = NULL;
if(is_resource($taskPoll[$tkey]["process"]))
{
$proc_status = proc_get_status($taskPoll[$tkey]["process"]);
if($proc_status['running']) if($proc_status['running'])
$runningtask++; $runningtask++;
else else
@@ -417,50 +464,337 @@ class task_Scheduler
$crashed = true; $crashed = true;
} }
} }
}
if ($crashed === true && $ttask[$tkey]["task"]->get_status() === task_abstract::RETURNSTATUS_TORESTART) if(!$crashed && !$taskPoll[$tkey]['task']->get_pid())
$crashed = true;
if(!$crashed)
{
$taskPoll[$tkey]["killat"] = NULL;
$runningtask++;
}
else
{
// crashed !
$taskPoll[$tkey]["task"]->increment_crash_counter();
if($this->method == self::METHOD_PROC_OPEN)
{
@fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($taskPoll[$tkey]["process"]);
$taskPoll[$tkey]["process"] = null;
}
$this->log(
sprintf(
"Task %s crashed %d times"
, $taskPoll[$tkey]["task"]->get_task_id()
, $taskPoll[$tkey]["task"]->get_crash_counter()
)
);
if($taskPoll[$tkey]["task"]->get_crash_counter() > 5)
$taskPoll[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED);
else
$taskPoll[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART);
}
break;
case task_abstract::STATUS_TOSTOP:
if($taskPoll[$tkey]["killat"] === NULL)
$taskPoll[$tkey]["killat"] = time() + self::TASKDELAYTOQUIT;
$tpid = $taskPoll[$tkey]['task']->get_pid();
if($tpid)
{
if(($dt = $taskPoll[$tkey]["killat"] - time()) < 0)
{
if($this->method == self::METHOD_PROC_OPEN)
{
$pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid $tpid`);
foreach($pids as $pid)
{
if(is_numeric($pid))
{
$this->log("Killing pid %d", $pid);
posix_kill($pid, 9);
}
}
}
elseif($this->method == self::METHOD_FORK)
{
posix_kill($tpid, 9);
}
$this->log(
sprintf(
"SIGKILL sent to task %s (pid=%s)"
, $taskPoll[$tkey]["task"]->get_task_id()
, $tpid
)
);
if($this->method == self::METHOD_PROC_OPEN)
{
proc_terminate($taskPoll[$tkey]["process"], 9);
@fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($taskPoll[$tkey]["pipes"][2]);
proc_close($taskPoll[$tkey]["process"]);
}
unlink($lockdir . 'task_' . $taskPoll[$tkey]['task']->get_task_id() . '.lock');
$taskPoll[$tkey]["task"]->increment_crash_counter();
// $taskPoll[$tkey]["task"]->set_pid(null);
$taskPoll[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED);
}
else
{
$this->log(
sprintf(
"waiting task %s to quit (kill in %d seconds)"
, $taskPoll[$tkey]["task"]->get_task_id()
, $dt
)
);
$runningtask++;
}
}
else
{
$this->log(
sprintf(
"task %s has quit"
, $taskPoll[$tkey]["task"]->get_task_id()
)
);
}
break;
case task_abstract::RETURNSTATUS_STOPPED:
case task_abstract::RETURNSTATUS_TODELETE:
if($this->method == self::METHOD_PROC_OPEN)
{
if($taskPoll[$tkey]["process"])
{
@fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($taskPoll[$tkey]["process"]);
$taskPoll[$tkey]["process"] = null;
}
}
break;
}
}
/*
$common_status = array(
task_abstract::STATUS_STARTED
, task_abstract::RETURNSTATUS_STOPPED
);
foreach($taskPoll as $tkey => $tv)
{
// if (!in_array($taskPoll[$tkey]["task"]->get_status(), $common_status))
// {
// $this->log(
// sprintf(
// 'task %s has status %s'
// , $taskPoll[$tkey]["task"]->get_task_id()
// , $taskPoll[$tkey]["task"]->get_status()
// )
// );
// }
switch($tv['task']->get_status())
{
default:
$this->log(sprintf('Unknow status `%s`', $tv['task']->get_status()));
break;
case task_abstract::RETURNSTATUS_TORESTART:
if(!$taskPoll[$tkey]['task']->get_pid())
{
@fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($taskPoll[$tkey]["process"]);
$taskPoll[$tkey]["process"] = null;
if($schedstatus == 'started')
{
$taskPoll[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART);
}
// trick to start the task immediatly : DON'T break if ending with 'tostart'
// so it will continue with 'tostart' case !
}
else
{
break;
}
case task_abstract::STATUS_TOSTART:
// if scheduler is 'tostop', don't launch a new task !
if($schedstatus != 'started')
break;
$taskPoll[$tkey]["killat"] = NULL;
if(!$taskPoll[$tkey]["process"])
{
$descriptors = array(
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
if($log_tasks === true)
{
$descriptors[1] = array(
"file"
, $logdir . "task_$tkey.log"
, "a+"
);
$descriptors[2] = array(
"file"
, $logdir . "task_$tkey.error.log"
, "a+"
);
}
$taskPoll[$tkey]["process"] = proc_open(
$taskPoll[$tkey]["cmd"].' '.implode(' ', $taskPoll[$tkey]["args"])
, $descriptors
, $taskPoll[$tkey]["pipes"]
, $registry->get('GV_RootPath') . "bin/"
, null
, array('bypass_shell' => true)
);
if(is_resource($taskPoll[$tkey]["process"]))
{
sleep(2); // let the process lock and write it's pid
}
if(is_resource($taskPoll[$tkey]["process"]) && $taskPoll[$tkey]['task']->get_pid() !== null)
{
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : RUNNING ? : pid=%s \n", __FILE__, __LINE__, $taskPoll[$tkey]['task']->get_pid()), FILE_APPEND);
$this->log(
sprintf(
"Task %s '%s' started (pid=%s)"
, $taskPoll[$tkey]['task']->get_task_id()
, $taskPoll[$tkey]["cmd"]
, $taskPoll[$tkey]['task']->get_pid()
)
);
$runningtask++;
}
else
{
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : NOT RUNNING ? : pid=%s \n", __FILE__, __LINE__, $taskPoll[$tkey]['task']->get_pid()), FILE_APPEND);
$taskPoll[$tkey]["task"]->increment_crash_counter();
@fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($taskPoll[$tkey]["process"]);
$taskPoll[$tkey]["process"] = null;
$this->log(
sprintf(
"Task %s '%s' failed to start %d times"
, $taskPoll[$tkey]["task"]->get_task_id()
, $taskPoll[$tkey]["cmd"]
, $taskPoll[$tkey]["task"]->get_crash_counter()
)
);
if($taskPoll[$tkey]["task"]->get_crash_counter() > 5)
{
$taskPoll[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED);
}
else
{
$taskPoll[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART);
}
}
}
break;
case task_abstract::STATUS_STARTED:
$crashed = false;
// If no process, the task is probably manually ran
if($taskPoll[$tkey]["process"])
{
$taskPoll[$tkey]["killat"] = NULL;
// if(is_resource($taskPoll[$tkey]["process"]))
// {
// $proc_status = proc_get_status($taskPoll[$tkey]["process"]);
// if($proc_status['running'])
// $runningtask++;
// else
// $crashed = true;
// }
// else
// {
// $crashed = true;
// }
if($taskPoll[$tkey]['task']->get_pid())
$runningtask++;
else
$crashed = true;
}
if($crashed === true && $taskPoll[$tkey]["task"]->get_status() === task_abstract::RETURNSTATUS_TORESTART)
{ {
$crashed = false; $crashed = false;
} }
if($crashed) if($crashed)
{ {
$ttask[$tkey]["task"]->increment_crash_counter(); $taskPoll[$tkey]["task"]->increment_crash_counter();
@fclose($ttask[$tkey]["pipes"][1]); @fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($ttask[$tkey]["pipes"][2]); @fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($ttask[$tkey]["process"]); @proc_close($taskPoll[$tkey]["process"]);
$ttask[$tkey]["process"] = null; $taskPoll[$tkey]["process"] = null;
$this->log( $this->log(
sprintf( sprintf(
"Task %s crashed %d times" "Task %s crashed %d times"
, $ttask[$tkey]["task"]->get_task_id() , $taskPoll[$tkey]["task"]->get_task_id()
, $ttask[$tkey]["task"]->get_crash_counter() , $taskPoll[$tkey]["task"]->get_crash_counter()
) )
); );
$ttask[$tkey]["task"]->increment_crash_counter(); if($taskPoll[$tkey]["task"]->get_crash_counter() > 5)
if ($ttask[$tkey]["task"]->get_crash_counter() > 5)
{ {
$ttask[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED); $taskPoll[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED);
} }
else else
{ {
$ttask[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART); $taskPoll[$tkey]["task"]->set_status(task_abstract::STATUS_TOSTART);
} }
} }
break; break;
case task_abstract::STATUS_TOSTOP: case task_abstract::STATUS_TOSTOP:
if ($ttask[$tkey]["process"]) if($taskPoll[$tkey]["process"])
{ {
if ($ttask[$tkey]["killat"] === NULL) if($taskPoll[$tkey]["killat"] === NULL)
$ttask[$tkey]["killat"] = time() + self::TASKDELAYTOQUIT; $taskPoll[$tkey]["killat"] = time() + self::TASKDELAYTOQUIT;
if (($dt = $ttask[$tkey]["killat"] - time()) < 0)
if(($dt = $taskPoll[$tkey]["killat"] - time()) < 0)
{ {
$ppid = $ttask[$tkey]['task']->get_pid(); $ppid = $taskPoll[$tkey]['task']->get_pid();
$pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid $ppid`); $pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid $ppid`);
foreach($pids as $pid) foreach($pids as $pid)
{ {
@@ -474,27 +808,27 @@ class task_Scheduler
$this->log( $this->log(
sprintf( sprintf(
"SIGKILL sent to task %s (pid=%s)" "SIGKILL sent to task %s (pid=%s)"
, $ttask[$tkey]["task"]->get_task_id() , $taskPoll[$tkey]["task"]->get_task_id()
, $ttask[$tkey]["task"]->get_pid() , $taskPoll[$tkey]["task"]->get_pid()
) )
); );
proc_terminate($ttask[$tkey]["process"], 9); proc_terminate($taskPoll[$tkey]["process"], 9);
@fclose($ttask[$tkey]["pipes"][1]); @fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($ttask[$tkey]["pipes"][2]); @fclose($taskPoll[$tkey]["pipes"][2]);
proc_close($ttask[$tkey]["process"]); proc_close($taskPoll[$tkey]["process"]);
unlink($lockdir . 'task_' . $ttask[$tkey]['task']->get_task_id() . '.lock'); unlink($lockdir . 'task_' . $taskPoll[$tkey]['task']->get_task_id() . '.lock');
$ttask[$tkey]["task"]->increment_crash_counter(); $taskPoll[$tkey]["task"]->increment_crash_counter();
// $ttask[$tkey]["task"]->set_pid(null); // $taskPoll[$tkey]["task"]->set_pid(null);
$ttask[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED); $taskPoll[$tkey]["task"]->set_status(task_abstract::RETURNSTATUS_STOPPED);
} }
else else
{ {
$this->log( $this->log(
sprintf( sprintf(
"waiting task %s to quit (kill in %d seconds)" "waiting task %s to quit (kill in %d seconds)"
, $ttask[$tkey]["task"]->get_task_id() , $taskPoll[$tkey]["task"]->get_task_id()
, $dt , $dt
) )
); );
@@ -505,18 +839,29 @@ class task_Scheduler
case task_abstract::RETURNSTATUS_STOPPED: case task_abstract::RETURNSTATUS_STOPPED:
case task_abstract::RETURNSTATUS_TODELETE: case task_abstract::RETURNSTATUS_TODELETE:
if ($ttask[$tkey]["process"]) if($taskPoll[$tkey]["process"])
{ {
@fclose($ttask[$tkey]["pipes"][1]); @fclose($taskPoll[$tkey]["pipes"][1]);
@fclose($ttask[$tkey]["pipes"][2]); @fclose($taskPoll[$tkey]["pipes"][2]);
@proc_close($ttask[$tkey]["process"]); @proc_close($taskPoll[$tkey]["process"]);
$ttask[$tkey]["process"] = null; $taskPoll[$tkey]["process"] = null;
} }
break; break;
} }
} }
*/
$to_reopen = false; $to_reopen = false;
if($conn->ping()) if($conn->ping())
{ {

View File

@@ -21,6 +21,8 @@ abstract class task_abstract
const STATE_MAXRECSDONE = 'STATE_MAXRECS'; const STATE_MAXRECSDONE = 'STATE_MAXRECS';
const STATE_FINISHED = 'STATE_FINISHED'; const STATE_FINISHED = 'STATE_FINISHED';
const SIGNAL_SCHEDULER_DIED = 'SIGNAL_SCHEDULER_DIED';
protected $suicidable = false; protected $suicidable = false;
protected $launched_by = 0; protected $launched_by = 0;
@@ -145,18 +147,17 @@ abstract class task_abstract
return $this->task_status; return $this->task_status;
} }
public function set_pid($pid) // public function set_pid($pid)
{ // {
$conn = connection::getPDOConnection(); // $conn = connection::getPDOConnection();
//
$sql = 'UPDATE task2 SET pid = :pid WHERE task_id = :taskid'; // $sql = 'UPDATE task2 SET pid = :pid WHERE task_id = :taskid';
$stmt = $conn->prepare($sql); // $stmt = $conn->prepare($sql);
$stmt->execute(array(':pid' => $pid, ':taskid' => $this->get_task_id())); // $stmt->execute(array(':pid' => $pid, ':taskid' => $this->get_task_id()));
$stmt->closeCursor(); // $stmt->closeCursor();
//
return $this; // return $this;
} // }
// 'active' means 'auto-start when scheduler starts' // 'active' means 'auto-start when scheduler starts'
public function set_active($boolean) public function set_active($boolean)
{ {
@@ -221,6 +222,7 @@ abstract class task_abstract
{ {
return $this->crash_counter; return $this->crash_counter;
} }
public function increment_crash_counter() public function increment_crash_counter()
{ {
$conn = connection::getPDOConnection(); $conn = connection::getPDOConnection();
@@ -293,7 +295,10 @@ abstract class task_abstract
{ {
$this->log($e->getMessage()); $this->log($e->getMessage());
$this->log(("Warning : abox connection lost, restarting in 10 min.")); $this->log(("Warning : abox connection lost, restarting in 10 min."));
sleep(60 * 10);
for($t = 60 * 10; $t > 0; $t--) // DON'T do sleep(600) because it prevents ticks !
sleep(1);
$this->running = false; $this->running = false;
return(''); return('');
@@ -402,18 +407,60 @@ abstract class task_abstract
public function get_pid() public function get_pid()
{ {
$conn = connection::getPDOConnection(); $pid = NULL;
$sql = 'SELECT pid FROM task2 WHERE task_id = :taskid';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':taskid' => $this->get_task_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$pid = $row ? $row['pid'] : null; $taskid = $this->get_task_id();
$registry = registry::get_instance();
system_file::mkdir($lockdir = $registry->get('GV_RootPath') . 'tmp/locks/');
if(($fd = fopen(($lockfile = ($lockdir . 'task_' . $taskid . '.lock')), 'a+')))
{
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : fopen(%s) \n", __FILE__, __LINE__, $lockfile), FILE_APPEND);
if(flock($fd, LOCK_EX | LOCK_NB) === FALSE)
{
// already locked ? : task running
$pid = fgets($fd);
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : can't flock() : pid=%s \n", __FILE__, __LINE__, $pid), FILE_APPEND);
}
else
{
// can lock : not running
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : NOT RUNNING can flock() : pid=%s \n", __FILE__, __LINE__, file_get_contents($lockfile)), FILE_APPEND);
flock($fd, LOCK_UN);
}
fclose($fd);
}
return $pid; return $pid;
} }
/*
public function is_running()
{
$retval = false;
$registry = registry::get_instance();
$lockdir = $registry->get('GV_RootPath') . 'tmp/locks/';
$tasklock = fopen($lockfile = ($lockdir . '/task_' . $this->get_task_id() . '.lock'), 'a+');
if (flock($tasklock, LOCK_SH | LOCK_NB) != true)
{
$retval = true;
}
else
{
ftruncate($tasklock, 0);
flock($tasklock, LOCK_UN | LOCK_NB);
fclose($tasklock);
unlink($lockfile);
}
return $retval;
}
*/
protected function check_current_state() protected function check_current_state()
{ {
switch($this->current_state) switch($this->current_state)
@@ -485,13 +532,18 @@ abstract class task_abstract
$conn = connection::getPDOConnection(); $conn = connection::getPDOConnection();
$conn->close(); $conn->close();
unset($conn); unset($conn);
sleep($this->period - $when_started); // sleep($this->period - $when_started);
for($t = $this->period - $when_started; $t > 0; $t--) // DON'T do sleep($this->period - $when_started) because it prevents ticks !
sleep(1);
} }
} }
} }
final public function run($runner) final public function run($runner)
{ {
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : LAUNCHING : tid=%s \n", __FILE__, __LINE__, $this->get_task_id()), FILE_APPEND);
$taskid = $this->get_task_id(); $taskid = $this->get_task_id();
$conn = connection::getPDOConnection(); $conn = connection::getPDOConnection();
@@ -499,8 +551,10 @@ abstract class task_abstract
system_file::mkdir($lockdir = $registry->get('GV_RootPath') . 'tmp/locks/'); system_file::mkdir($lockdir = $registry->get('GV_RootPath') . 'tmp/locks/');
$locker = true; $locker = true;
$tasklock = fopen(($lockfile = ($lockdir . 'task_' . $taskid . '.lock')), 'a+'); $tasklock = fopen(($lockfile = ($lockdir . 'task_' . $taskid . '.lock')), 'a+');
if (flock($tasklock, LOCK_EX | LOCK_NB, $locker) != true) if(flock($tasklock, LOCK_EX | LOCK_NB, $locker) === FALSE)
{ {
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : LAUNCH OPENED AND CANT LOCK : pid=%s \n", __FILE__, __LINE__, getmypid()), FILE_APPEND);
printf(("runtask::ERROR : task already running.\n"), $taskid); printf(("runtask::ERROR : task already running.\n"), $taskid);
fclose($tasklock); fclose($tasklock);
@@ -511,6 +565,8 @@ abstract class task_abstract
ftruncate($tasklock, 0); ftruncate($tasklock, 0);
fwrite($tasklock, '' . getmypid()); fwrite($tasklock, '' . getmypid());
fflush($tasklock); fflush($tasklock);
// ************************************************
// file_put_contents("/tmp/scheduler2.log", sprintf("%s [%d] : LAUNCH OPENED AND LOCKED : pid=%s \n", __FILE__, __LINE__, getmypid()), FILE_APPEND);
} }
$this->set_runner($runner); $this->set_runner($runner);
@@ -536,28 +592,6 @@ abstract class task_abstract
abstract protected function run2(); abstract protected function run2();
public function is_running()
{
$retval = false;
$registry = registry::get_instance();
$lockdir = $registry->get('GV_RootPath') . 'tmp/locks/';
$tasklock = fopen($lockfile = ($lockdir . '/task_' . $this->get_task_id() . '.lock'), 'a+');
if (flock($tasklock, LOCK_SH | LOCK_NB) != true)
{
$retval = true;
}
else
{
ftruncate($tasklock, 0);
flock($tasklock, LOCK_UN | LOCK_NB);
fclose($tasklock);
unlink($lockfile);
}
return $retval;
}
protected function load_settings(SimpleXMLElement $sx_task_settings) protected function load_settings(SimpleXMLElement $sx_task_settings)
{ {
$this->period = (int) $sx_task_settings->period; $this->period = (int) $sx_task_settings->period;

View File

@@ -17,7 +17,6 @@
*/ */
abstract class task_databoxAbstract extends task_abstract abstract class task_databoxAbstract extends task_abstract
{ {
// abstract public function help(); // abstract public function help();
// //
// abstract public function getName(); // abstract public function getName();
@@ -44,7 +43,10 @@ abstract class task_databoxAbstract extends task_abstract
{ {
$this->log($e->getMessage()); $this->log($e->getMessage());
$this->log(("Warning : abox connection lost, restarting in 10 min.")); $this->log(("Warning : abox connection lost, restarting in 10 min."));
sleep(60 * 10);
for($t = 60 * 10; $t; $t--) // DON'T do sleep(600) because it prevents ticks !
sleep(1);
$this->running = false; $this->running = false;
$this->return_value = self::RETURNSTATUS_TORESTART; $this->return_value = self::RETURNSTATUS_TORESTART;
@@ -188,4 +190,3 @@ abstract class task_databoxAbstract extends task_abstract
} }
} }

View File

@@ -90,34 +90,26 @@ class task_manager
continue; continue;
try try
{ {
if( ($lock = fopen( $lockdir . 'task.'.$row['task_id'].'.lock', 'a+')) ) // if( ($lock = fopen( $lockdir . 'task.'.$row['task_id'].'.lock', 'a+')) )
{ // {
if (flock($lock, LOCK_SH | LOCK_NB) === FALSE) // if (flock($lock, LOCK_SH | LOCK_NB) === FALSE)
{ // {
// already locked : running ! // // already locked : running !
$row['pid'] = fgets($lock, 512); // $row['pid'] = fgets($lock, 512);
} // }
else // else
{ // {
// can lock : not running // // can lock : not running
flock($lock, LOCK_UN); // flock($lock, LOCK_UN);
} // }
fclose($lock); // fclose($lock);
} // }
$tasks[$row['task_id']] = new $classname($row['task_id']); $tasks[$row['task_id']] = new $classname($row['task_id']);
} }
catch (Exception $e) catch (Exception $e)
{ {
} }
} }
$this->tasks = $tasks; $this->tasks = $tasks;
@@ -175,7 +167,12 @@ class task_manager
public function get_scheduler_state2() public function get_scheduler_state2()
{ {
$ret = array('pid'=>NULL, 'qdelay'=>NULL); $sql = "SELECT UNIX_TIMESTAMP()-UNIX_TIMESTAMP(schedqtime) AS qdelay, schedstatus AS status FROM sitepreff";
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute();
$ret = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$ret['pid'] = NULL;
$appbox = appbox::get_instance(); $appbox = appbox::get_instance();
$lockdir = $appbox->get_registry()->get('GV_RootPath') . 'tmp/locks/'; $lockdir = $appbox->get_registry()->get('GV_RootPath') . 'tmp/locks/';
@@ -184,12 +181,6 @@ class task_manager
if (flock($schedlock, LOCK_SH | LOCK_NB) === FALSE) if (flock($schedlock, LOCK_SH | LOCK_NB) === FALSE)
{ {
// already locked : running ! // already locked : running !
$sql = "SELECT UNIX_TIMESTAMP()-UNIX_TIMESTAMP(schedqtime) AS qdelay FROM sitepreff";
$stmt = $this->appbox->get_connection()->prepare($sql);
$stmt->execute();
$ret = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$ret['pid'] = fgets($schedlock, 512); $ret['pid'] = fgets($schedlock, 512);
} }
else else

View File

@@ -107,9 +107,7 @@ switch ($parm['action'])
break; break;
case 'SETTASKSTATUS': case 'SETTASKSTATUS':
$parm = $request->get_parms("task_id", "status"); $parm = $request->get_parms("task_id", "status");
try try
{ {
$task_manager = new task_manager($appbox); $task_manager = new task_manager($appbox);
@@ -120,13 +118,10 @@ switch ($parm['action'])
{ {
} }
break; break;
case 'SETSCHEDSTATUS': case 'SETSCHEDSTATUS':
$parm = $request->get_parms('status'); $parm = $request->get_parms('status');
try try
{ {
$task_manager = new task_manager($appbox); $task_manager = new task_manager($appbox);
@@ -145,10 +140,9 @@ switch ($parm['action'])
$output = $ret->saveXML(); $output = $ret->saveXML();
break; break;
case 'RESETTASKCRASHCOUNTER': case 'RESETTASKCRASHCOUNTER':
$parm = $request->get_parms("task_id"); $parm = $request->get_parms("task_id");
try try
{ {
$task_manager = new task_manager($appbox); $task_manager = new task_manager($appbox);
@@ -166,15 +160,10 @@ switch ($parm['action'])
$root->appendChild($ret->createCDATASection(var_export($parm, true))); $root->appendChild($ret->createCDATASection(var_export($parm, true)));
$output = $ret->saveXML(); $output = $ret->saveXML();
break; break;
case 'CHANGETASK': case 'CHANGETASK':
$parm = $request->get_parms('act', 'task_id', "usr"); $parm = $request->get_parms('act', 'task_id', "usr");
$ret = new DOMDocument("1.0", "UTF-8"); $ret = new DOMDocument("1.0", "UTF-8");
$ret->standalone = true; $ret->standalone = true;
$ret->preserveWhiteSpace = false; $ret->preserveWhiteSpace = false;
@@ -200,7 +189,7 @@ switch ($parm['action'])
$output = $ret->saveXML(); $output = $ret->saveXML();
break; break;
/*
case 'PINGSCHEDULER': case 'PINGSCHEDULER':
$lockdir = $registry->get('GV_RootPath') . 'tmp/locks/'; $lockdir = $registry->get('GV_RootPath') . 'tmp/locks/';
@@ -267,7 +256,7 @@ switch ($parm['action'])
break; break;
*/
case 'PINGSCHEDULER_JS': case 'PINGSCHEDULER_JS':
$ret = array(); $ret = array();
$ret['time'] = $dat = date("H:i:s"); $ret['time'] = $dat = date("H:i:s");
@@ -284,6 +273,7 @@ switch ($parm['action'])
, 'pid' =>$task->get_pid() , 'pid' =>$task->get_pid()
, 'crashed'=>$task->get_crash_counter() , 'crashed'=>$task->get_crash_counter()
, 'completed'=>$task->get_completed_percentage() , 'completed'=>$task->get_completed_percentage()
, 'status'=>$task->get_status()
); );
$ret['tasks'][$_t['id']] = $_t; $ret['tasks'][$_t['id']] = $_t;
} }

View File

@@ -107,11 +107,12 @@ $task_manager = new task_manager($appbox);
editTask(tid); editTask(tid);
break; break;
case "start": case "start":
setTaskStatus(tid, 'tostart'); setTaskStatus(tid, 'tostart', true); // true : reset crash counter
break; break;
case "stop": case "stop":
setTaskStatus(tid, 'tostop'); setTaskStatus(tid, 'tostop', false);
break; break;
/*
case "fix": case "fix":
switch(T_task[tid]) switch(T_task[tid])
{ {
@@ -135,6 +136,7 @@ $task_manager = new task_manager($appbox);
break; break;
} }
break; break;
*/
case 'delete': case 'delete':
switch(T_task[tid]) switch(T_task[tid])
{ {
@@ -222,7 +224,7 @@ foreach($tasks as $t)
$('#newTaskButton').contextMenu( $('#newTaskButton').contextMenu(
menuNewTask, menuNewTask,
{ {
theme:'vista' // theme:'vista'
} }
); );
@@ -358,7 +360,7 @@ foreach($tasks as $t)
); );
self.setTimeout("pingScheduler();", 100); self.setTimeout("pingScheduler(true);", 100); // true : loop forever each 2 sec
}) })
</script> </script>
</head> </head>
@@ -469,18 +471,27 @@ foreach($tasks as $t)
document.forms["task"].submit(); document.forms["task"].submit();
} }
function setTaskStatus(tid, status) function setTaskStatus(tid, status, resetCrashCounter)
{
if(resetCrashCounter)
{ {
var url = "/admin/adminFeedback.php";
url += "?action=SETTASKSTATUS&task_id=" + encodeURIComponent(tid);
url += "&status=" + encodeURIComponent(status);
$.ajax({ $.ajax({
url: url, url: "/admin/adminFeedback.php",
data : { task_id:tid, action:"RESETTASKCRASHCOUNTER" },
dataType:'xml', dataType:'xml',
success: function(ret) success: function(ret)
{ {
}
});
}
$.ajax({
url: "/admin/adminFeedback.php",
data : {task_id:tid, action:"SETTASKSTATUS", status:status},
dataType:'xml',
success: function(ret)
{
pingScheduler(false); // false : just one time
} }
}); });
} }
@@ -488,15 +499,13 @@ foreach($tasks as $t)
function setSchedStatus(status) function setSchedStatus(status)
{ {
var url = "/admin/adminFeedback.php";
url += "?action=SETSCHEDSTATUS&status=" + encodeURIComponent(status);
$.ajax({ $.ajax({
url: url, url: "/admin/adminFeedback.php",
data : { action:"SETSCHEDSTATUS", status:status },
dataType:'xml', dataType:'xml',
success: function(ret) success: function(ret)
{ {
pingScheduler(false); // false : just one time
} }
}); });
} }
@@ -512,7 +521,7 @@ foreach($tasks as $t)
document.forms["taskManager"].submit(); document.forms["taskManager"].submit();
} }
} }
/*
function old_pingScheduler() function old_pingScheduler()
{ {
$.ajax({ $.ajax({
@@ -652,9 +661,10 @@ foreach($tasks as $t)
} }
}); });
} }
*/
function pingScheduler() function pingScheduler(repeat)
{ {
$.ajax({ $.ajax({
url: '/admin/adminFeedback.php?action=PINGSCHEDULER_JS', url: '/admin/adminFeedback.php?action=PINGSCHEDULER_JS',
@@ -663,22 +673,37 @@ foreach($tasks as $t)
{ {
retPing = ret; // global retPing = ret; // global
$("#pingTime").empty().append(ret.time); $("#pingTime").empty().append(ret.time);
if(ret.scheduler && ret.scheduler.pid) if(ret.scheduler)
{ {
if(ret.scheduler.status)
$("#STATUS_SCHED").html(ret.scheduler.status);
else
$("#STATUS_SCHED").html('');
if(ret.scheduler.pid)
$("#PID_SCHED").html(ret.scheduler.pid); $("#PID_SCHED").html(ret.scheduler.pid);
else
$("#PID_SCHED").html('-');
} }
else else
{ {
$("#STATUS_SCHED").html('');
$("#PID_SCHED").html('-'); $("#PID_SCHED").html('-');
} }
if(ret.tasks) if(ret.tasks)
{ {
for(id in ret.tasks) for(id in ret.tasks)
{ {
if(ret.tasks[id].status)
$("#STATUS_"+id).html(ret.tasks[id].status);
else
$("#STATUS_"+id).html('');
if(ret.tasks[id].pid) if(ret.tasks[id].pid)
$("#PID_"+id).html(ret.tasks[id].pid); $("#PID_"+id).html(ret.tasks[id].pid);
else else
$("#PID_"+id).html('-'); $("#PID_"+id).html('-');
if(ret.tasks[id].completed && ret.tasks[id].completed>0 && ret.tasks[id].completed<=100) if(ret.tasks[id].completed && ret.tasks[id].completed>0 && ret.tasks[id].completed<=100)
{ {
$("#COMP_"+id).width(ret.tasks[id].completed + "%"); $("#COMP_"+id).width(ret.tasks[id].completed + "%");
@@ -691,8 +716,8 @@ foreach($tasks as $t)
} }
} }
} }
if(repeat)
self.setTimeout("pingScheduler();", 3000); self.setTimeout("pingScheduler(true);", 1000);
} }
}); });
} }