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'
@@ -54,21 +59,56 @@ class module_console_taskrun extends Command
$task_id = (int) $input->getArgument('task_id'); $task_id = (int) $input->getArgument('task_id');
if ($task_id <= 0 || strlen($task_id) !== strlen($input->getArgument('task_id'))) if($task_id <= 0 || strlen($task_id) !== strlen($input->getArgument('task_id')))
throw new \RuntimeException('Argument must be an Id.'); throw new \RuntimeException('Argument must be an Id.');
$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();
}
}
} }

File diff suppressed because it is too large Load Diff

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;
@@ -129,7 +131,7 @@ abstract class task_abstract
, self::RETURNSTATUS_TORESTART , self::RETURNSTATUS_TORESTART
, self::STATUS_TOSTART , self::STATUS_TOSTART
); );
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));
@@ -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();
@@ -268,9 +270,9 @@ abstract class task_abstract
$this->system = system_server::get_platform(); $this->system = system_server::get_platform();
$this->launched_by = array_key_exists("REQUEST_URI", $_SERVER) ? self::LAUCHED_BY_BROWSER : self::LAUCHED_BY_COMMANDLINE; $this->launched_by = array_key_exists("REQUEST_URI", $_SERVER) ? self::LAUCHED_BY_BROWSER : self::LAUCHED_BY_COMMANDLINE;
if ($this->system != "DARWIN" && $this->system != "WINDOWS" && $this->system != "LINUX") if($this->system != "DARWIN" && $this->system != "WINDOWS" && $this->system != "LINUX")
{ {
if ($this->launched_by == self::LAUCHED_BY_COMMANDLINE) if($this->launched_by == self::LAUCHED_BY_COMMANDLINE)
{ {
// printf("Desole, ce programme ne fonctionne pas sous '" . $this->system . "'.\n"); // printf("Desole, ce programme ne fonctionne pas sous '" . $this->system . "'.\n");
flush(); flush();
@@ -279,7 +281,7 @@ abstract class task_abstract
} }
else else
{ {
if ($this->launched_by == self::LAUCHED_BY_COMMANDLINE) if($this->launched_by == self::LAUCHED_BY_COMMANDLINE)
{ {
flush(); flush();
} }
@@ -289,11 +291,14 @@ abstract class task_abstract
{ {
$conn = connection::getPDOConnection(); $conn = connection::getPDOConnection();
} }
catch (Exception $e) catch(Exception $e)
{ {
$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('');
@@ -304,7 +309,7 @@ abstract class task_abstract
$stmt->execute(array(':taskid' => $this->get_task_id())); $stmt->execute(array(':taskid' => $this->get_task_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor(); $stmt->closeCursor();
if (!$row) if(!$row)
throw new Exception('Unknown task id'); throw new Exception('Unknown task id');
$this->title = $row['name']; $this->title = $row['name'];
$this->crash_counter = (int) $row['crashed']; $this->crash_counter = (int) $row['crashed'];
@@ -357,7 +362,7 @@ abstract class task_abstract
$stmt->closeCursor(); $stmt->closeCursor();
$lock_file = $registry->get('GV_RootPath') . 'tmp/locks/task_' . $this->get_task_id() . '.lock'; $lock_file = $registry->get('GV_RootPath') . 'tmp/locks/task_' . $this->get_task_id() . '.lock';
if (is_writable($lock_file)) if(is_writable($lock_file))
unlink($lock_file); unlink($lock_file);
return; return;
@@ -366,7 +371,7 @@ abstract class task_abstract
protected function check_memory_usage() protected function check_memory_usage()
{ {
$current_memory = memory_get_usage(); $current_memory = memory_get_usage();
if ($current_memory >> 20 >= $this->maxmegs) if($current_memory >> 20 >= $this->maxmegs)
{ {
$this->log(sprintf( $this->log(sprintf(
"Max memory (%s M) reached (current is %s M)" "Max memory (%s M) reached (current is %s M)"
@@ -381,7 +386,7 @@ abstract class task_abstract
protected function check_records_done() protected function check_records_done()
{ {
if ($this->records_done >= (int) ($this->maxrecs)) if($this->records_done >= (int) ($this->maxrecs))
{ {
$this->current_state = self::STATE_MAXRECSDONE; $this->current_state = self::STATE_MAXRECSDONE;
} }
@@ -402,26 +407,68 @@ 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)
{ {
case self::STATE_MAXMEGSREACHED: case self::STATE_MAXMEGSREACHED:
case self::STATE_MAXRECSDONE: case self::STATE_MAXRECSDONE:
default: default:
if ($this->get_runner() == self::RUNNER_SCHEDULER) if($this->get_runner() == self::RUNNER_SCHEDULER)
{ {
$this->task_status = self::STATUS_TOSTOP; $this->task_status = self::STATUS_TOSTOP;
$this->return_value = self::RETURNSTATUS_TORESTART; $this->return_value = self::RETURNSTATUS_TORESTART;
@@ -429,7 +476,7 @@ abstract class task_abstract
break; break;
case self::STATE_FINISHED: case self::STATE_FINISHED:
$this->task_status = self::STATUS_TOSTOP; $this->task_status = self::STATUS_TOSTOP;
if ($this->suicidable === true) if($this->suicidable === true)
{ {
$this->return_value = self::RETURNSTATUS_TODELETE; $this->return_value = self::RETURNSTATUS_TODELETE;
$this->log('will hang myself'); $this->log('will hang myself');
@@ -458,13 +505,13 @@ abstract class task_abstract
$stmt->execute(array(':taskid' => $this->get_task_id())); $stmt->execute(array(':taskid' => $this->get_task_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor(); $stmt->closeCursor();
if (!$row || $row['status'] == 'tostop') if(!$row || $row['status'] == 'tostop')
{ {
$this->task_status = self::STATUS_TOSTOP; $this->task_status = self::STATUS_TOSTOP;
$this->return_value = self::RETURNSTATUS_STOPPED; $this->return_value = self::RETURNSTATUS_STOPPED;
} }
} }
catch (Exception $e) catch(Exception $e)
{ {
$this->return_value = self::RETURNSTATUS_STOPPED; $this->return_value = self::RETURNSTATUS_STOPPED;
$this->task_status = self::STATUS_TOSTOP; $this->task_status = self::STATUS_TOSTOP;
@@ -477,21 +524,26 @@ abstract class task_abstract
protected function pause($when_started=0) protected function pause($when_started=0)
{ {
$this->log($this->records_done . ' records done'); $this->log($this->records_done . ' records done');
if ($this->running)// && $this->records_done == 0) if($this->running)// && $this->records_done == 0)
{ {
$when_started = time() - $when_started; $when_started = time() - $when_started;
if ($when_started < $this->period) if($when_started < $this->period)
{ {
$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);
@@ -526,7 +582,7 @@ abstract class task_abstract
fclose($tasklock); fclose($tasklock);
@unlink($lockfile); @unlink($lockfile);
if ($this->return_value == self::RETURNSTATUS_TODELETE) if($this->return_value == self::RETURNSTATUS_TODELETE)
$this->delete(); $this->delete();
else else
$this->set_status($this->return_value); $this->set_status($this->return_value);
@@ -536,42 +592,20 @@ 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;
if ($this->period <= 0 || $this->period >= 60 * 60) if($this->period <= 0 || $this->period >= 60 * 60)
$this->period = 60; $this->period = 60;
$this->maxrecs = (int) $sx_task_settings->maxrecs; $this->maxrecs = (int) $sx_task_settings->maxrecs;
if ($sx_task_settings->maxrecs < 10 || $sx_task_settings->maxrecs > 1000) if($sx_task_settings->maxrecs < 10 || $sx_task_settings->maxrecs > 1000)
$this->maxrecs = 100; $this->maxrecs = 100;
$this->maxmegs = (int) $sx_task_settings->maxmegs; $this->maxmegs = (int) $sx_task_settings->maxmegs;
if ($sx_task_settings->maxmegs < 16 || $sx_task_settings->maxmegs > 512) if($sx_task_settings->maxmegs < 16 || $sx_task_settings->maxmegs > 512)
$this->maxmegs = 24; $this->maxmegs = 24;
$this->record_buffer_size = (int) $sx_task_settings->flush; $this->record_buffer_size = (int) $sx_task_settings->flush;
if ($sx_task_settings->flush < 1 || $sx_task_settings->flush > 100) if($sx_task_settings->flush < 1 || $sx_task_settings->flush > 100)
$this->record_buffer_size = 10; $this->record_buffer_size = 10;
return $this; return $this;
@@ -579,7 +613,7 @@ abstract class task_abstract
protected function increment_loops() protected function increment_loops()
{ {
if ($this->get_runner() == self::RUNNER_SCHEDULER && $this->loop > $this->maxloops) if($this->get_runner() == self::RUNNER_SCHEDULER && $this->loop > $this->maxloops)
{ {
$this->log(sprintf(('%d loops done, restarting'), $this->loop)); $this->log(sprintf(('%d loops done, restarting'), $this->loop));
$this->task_status = self::STATUS_TOSTOP; $this->task_status = self::STATUS_TOSTOP;
@@ -593,7 +627,7 @@ abstract class task_abstract
public function apply_task_status() public function apply_task_status()
{ {
if ($this->task_status == self::STATUS_TOSTOP) if($this->task_status == self::STATUS_TOSTOP)
{ {
$this->running = false; $this->running = false;
} }
@@ -605,7 +639,7 @@ abstract class task_abstract
{ {
static $lastt = null; static $lastt = null;
$t = explode(' ', ($ut = microtime())); $t = explode(' ', ($ut = microtime()));
if ($lastt === null) if($lastt === null)
$lastt = $t; $lastt = $t;
$dt = ($t[0] - $lastt[0]) + ($t[1] - $lastt[1]); $dt = ($t[0] - $lastt[0]) + ($t[1] - $lastt[1]);
@@ -638,7 +672,7 @@ abstract class task_abstract
*/ */
public static function create(appbox $appbox, $class_name, $settings = null) public static function create(appbox $appbox, $class_name, $settings = null)
{ {
if (!class_exists($class_name)) if(!class_exists($class_name))
throw new Exception('Unknown task class'); throw new Exception('Unknown task class');
$sql = 'INSERT INTO task2 $sql = 'INSERT INTO task2
@@ -649,9 +683,9 @@ abstract class task_abstract
:name, "0000/00/00 00:00:00", :class, :settings)'; :name, "0000/00/00 00:00:00", :class, :settings)';
if ($settings && !DOMDocument::loadXML($settings)) if($settings && !DOMDocument::loadXML($settings))
throw new Exception('settings invalide'); throw new Exception('settings invalide');
elseif (!$settings) elseif(!$settings)
$settings = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tasksettings>\n</tasksettings>"; $settings = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tasksettings>\n</tasksettings>";
$params = array( $params = array(
@@ -673,7 +707,7 @@ abstract class task_abstract
{ {
global $argc, $argv; global $argc, $argv;
$t = "usage: " . $argv[0] . " [options]\noptions:\n"; $t = "usage: " . $argv[0] . " [options]\noptions:\n";
foreach ($this->argt as $n => $v) foreach($this->argt as $n => $v)
$t .= "\t" . $n . $v["usage"] . "\n"; $t .= "\t" . $n . $v["usage"] . "\n";
return($t); return($t);
@@ -704,7 +738,7 @@ abstract class task_abstract
$stmt->closeCursor(); $stmt->closeCursor();
$this->completed_percentage = $p; $this->completed_percentage = $p;
} }
catch (Exception $e) catch(Exception $e)
{ {
} }

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();
@@ -34,17 +33,20 @@ abstract class task_databoxAbstract extends task_abstract
protected function run2() protected function run2()
{ {
while ($this->running) while($this->running)
{ {
try try
{ {
$conn = connection::getPDOConnection(); $conn = connection::getPDOConnection();
} }
catch (Exception $e) catch(Exception $e)
{ {
$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;
@@ -63,24 +65,24 @@ abstract class task_databoxAbstract extends task_abstract
$this->records_done = 0; $this->records_done = 0;
$duration = time(); $duration = time();
} }
catch (Exception $e) catch(Exception $e)
{ {
$this->task_status = self::STATUS_TOSTOP; $this->task_status = self::STATUS_TOSTOP;
$this->return_value = self::RETURNSTATUS_STOPPED; $this->return_value = self::RETURNSTATUS_STOPPED;
$rs = array(); $rs = array();
} }
foreach ($rs as $row) foreach($rs as $row)
{ {
if (!$this->running) if(!$this->running)
break; break;
$this->sbas_id = (int) $row['sbas_id']; $this->sbas_id = (int) $row['sbas_id'];
if ($this->mono_sbas_id && $this->sbas_id !== $this->mono_sbas_id) if($this->mono_sbas_id && $this->sbas_id !== $this->mono_sbas_id)
{ {
continue; continue;
} }
if ($this->mono_sbas_id) if($this->mono_sbas_id)
{ {
$this->log('This task works on ' . phrasea::sbas_names($this->mono_sbas_id)); $this->log('This task works on ' . phrasea::sbas_names($this->mono_sbas_id));
} }
@@ -89,7 +91,7 @@ abstract class task_databoxAbstract extends task_abstract
{ {
$this->load_settings(simplexml_load_string($row['settings'])); $this->load_settings(simplexml_load_string($row['settings']));
} }
catch (Exception $e) catch(Exception $e)
{ {
$this->log($e->getMessage()); $this->log($e->getMessage());
continue; continue;
@@ -126,7 +128,7 @@ abstract class task_databoxAbstract extends task_abstract
*/ */
$rs = $this->retrieve_sbas_content($databox); $rs = $this->retrieve_sbas_content($databox);
} }
catch (Exception $e) catch(Exception $e)
{ {
$this->log('Error : ' . $e->getMessage()); $this->log('Error : ' . $e->getMessage());
$rs = array(); $rs = array();
@@ -135,10 +137,10 @@ abstract class task_databoxAbstract extends task_abstract
$rowstodo = count($rs); $rowstodo = count($rs);
$rowsdone = 0; $rowsdone = 0;
if ($rowstodo > 0) if($rowstodo > 0)
$this->setProgress(0, $rowstodo); $this->setProgress(0, $rowstodo);
foreach ($rs as $row) foreach($rs as $row)
{ {
try try
{ {
@@ -148,7 +150,7 @@ abstract class task_databoxAbstract extends task_abstract
*/ */
$this->process_one_content($databox, $row); $this->process_one_content($databox, $row);
} }
catch (Exception $e) catch(Exception $e)
{ {
$this->log("Exception : " . $e->getMessage() $this->log("Exception : " . $e->getMessage()
. " " . basename($e->getFile()) . " " . $e->getLine()); . " " . basename($e->getFile()) . " " . $e->getLine());
@@ -166,7 +168,7 @@ abstract class task_databoxAbstract extends task_abstract
->check_records_done() ->check_records_done()
->check_task_status(); ->check_task_status();
if (!$this->running) if(!$this->running)
break; break;
} }
@@ -175,17 +177,16 @@ abstract class task_databoxAbstract extends task_abstract
->check_records_done() ->check_records_done()
->check_task_status(); ->check_task_status();
if ($connbas instanceof PDO) if($connbas instanceof PDO)
{ {
$connbas->close(); $connbas->close();
unset($connbas); unset($connbas);
} }
if ($rowstodo > 0) if($rowstodo > 0)
$this->setProgress(0, 0); $this->setProgress(0, 0);
return $this; return $this;
} }
} }

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,71 +136,72 @@ $task_manager = new task_manager($appbox);
break; break;
} }
break; break;
case 'delete': */
switch(T_task[tid]) case 'delete':
{ switch(T_task[tid])
case "stopped_0": {
case "started_0": case "stopped_0":
case "starting_0": case "started_0":
case "stopping_0": case "starting_0":
case "tostart_0": case "stopping_0":
case "tostop_0": case "tostart_0":
case "manual_0": case "tostop_0":
case "torestart_0": case "manual_0":
if(confirm("<?php echo p4string::MakeString(_('admin::tasks: supprimer la tache ?'), 'js', '"') ?>")) case "torestart_0":
{ if(confirm("<?php echo p4string::MakeString(_('admin::tasks: supprimer la tache ?'), 'js', '"') ?>"))
document.forms["taskManager"].target = ""; {
document.forms["taskManager"].act.value = "DELETETASK"; document.forms["taskManager"].target = "";
document.forms["taskManager"].tid.value = tid; document.forms["taskManager"].act.value = "DELETETASK";
document.forms["taskManager"].submit(); document.forms["taskManager"].tid.value = tid;
} document.forms["taskManager"].submit();
break;
} }
break; break;
case "log":
window.open("/admin/showlogtask.php?fil=<?php echo urlencode('task_t_') ?>"+tid+"%2Elog", "TASKLOG_"+tid);
break;
} }
break;
case "log":
window.open("/admin/showlogtask.php?fil=<?php echo urlencode('task_t_') ?>"+tid+"%2Elog", "TASKLOG_"+tid);
break;
} }
}
function preferencesScheduler() function preferencesScheduler()
{ {
var buttons = { var buttons = {
'<?php echo _('Fermer') ?>':function(){$('#scheduler-preferences').dialog('close').dialog('destroy')}, '<?php echo _('Fermer') ?>':function(){$('#scheduler-preferences').dialog('close').dialog('destroy')},
'<?php echo _('Renouveller') ?>':function(){renew_scheduler_key();} '<?php echo _('Renouveller') ?>':function(){renew_scheduler_key();}
}; };
$('#scheduler-preferences').dialog({ $('#scheduler-preferences').dialog({
width:400, width:400,
height:200, height:200,
modal:true, modal:true,
resizable:false, resizable:false,
draggable:false, draggable:false,
buttons:buttons buttons:buttons
}); });
} }
function renew_scheduler_key() function renew_scheduler_key()
{ {
var datas = {action:'SCHEDULERKEY', renew:'1'}; var datas = {action:'SCHEDULERKEY', renew:'1'};
$.post("/admin/adminFeedback.php" $.post("/admin/adminFeedback.php"
, datas , datas
, function(data){ , function(data){
$('#scheduler_key').val(data); $('#scheduler_key').val(data);
return; return;
}); });
} }
$(document).ready(function(){ $(document).ready(function(){
resized(); resized();
$(this).bind('resize',function(){resized();}); $(this).bind('resize',function(){resized();});
var allgetID = new Array ; var allgetID = new Array ;
var total = 0; var total = 0;
var menuNewTask = [ var menuNewTask = [
<?php <?php
// fill the 'new task' menu // fill the 'new task' menu
$tasks = task_manager::getAvailableTasks(); $tasks = task_manager::getAvailableTasks();
@@ -216,150 +218,150 @@ foreach($tasks as $t)
printf(" }%s\n", --$ntasks ? ',' : ''); printf(" }%s\n", --$ntasks ? ',' : '');
} }
?> ?>
]; ];
$('#newTaskButton').contextMenu( $('#newTaskButton').contextMenu(
menuNewTask, menuNewTask,
{
// theme:'vista'
}
);
$('.dropdown.scheduler').contextMenu(
[
{ {
theme:'vista' 'Start':
} {
); onclick:function(menuItem,menu) { doMenuSched('start'); },
title:'Demarrer le TaskManager'
$('.dropdown.scheduler').contextMenu(
[
{
'Start':
{
onclick:function(menuItem,menu) { doMenuSched('start'); },
title:'Demarrer le TaskManager'
}
},
{
'Stop':
{
onclick:function(menuItem,menu) { doMenuSched('stop'); },
title:'Arreter le TaskManager'
}
},
$.contextMenu.separator,
{
'Show log':
{
onclick:function(menuItem,menu) { doMenuSched('log'); },
title:'Afficher les logs'
}
},
{
'Preferences':
{
onclick:function(menuItem,menu) { doMenuSched('preferences'); },
title:'Scheduler preferences'
}
} }
] },
,
{ {
// theme:'vista', 'Stop':
optionsIdx:{'start':0, 'stop':1}, {
doclick:function(item) onclick:function(menuItem,menu) { doMenuSched('stop'); },
title:'Arreter le TaskManager'
}
},
$.contextMenu.separator,
{
'Show log':
{
onclick:function(menuItem,menu) { doMenuSched('log'); },
title:'Afficher les logs'
}
},
{
'Preferences':
{
onclick:function(menuItem,menu) { doMenuSched('preferences'); },
title:'Scheduler preferences'
}
}
]
,
{
// theme:'vista',
optionsIdx:{'start':0, 'stop':1},
doclick:function(item)
{
console.log(item);
},
beforeShow:function()
{
if(!retPing)
return;
if(retPing.scheduler && retPing.scheduler.pid)
{ {
console.log(item); $(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').removeClass("context-menu-item-disabled");
}, $(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').addClass("context-menu-item-disabled");
beforeShow:function() }
else
{ {
if(!retPing) $(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').addClass("context-menu-item-disabled");
return; $(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').removeClass("context-menu-item-disabled");
}
}
}
);
$('.task_manager .dropdown.task').contextMenu(
[
{
'Edit':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'edit'); },
title:'Modifier cette tache'
}
},
{
'Start':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'start'); },
title:'Demarrer cette tache'
}
},
{
'Stop':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'stop'); },
title:'Arreter cette tache'
}
},
{
'Delete':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'delete'); },
title:'Supprimer cette tache'
}
},
$.contextMenu.separator,
{
'Show log':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'log'); },
title:'Afficher les logs'
}
}
],
{
optionsIdx:{'edit':0, 'start':1, 'stop':2, 'delete':3, 'log':5},
doclick:function()
{
},
beforeShow:function()
{
var tid = $($(this)[0].target).parent().attr('id').split('_').pop();
if(!retPing || !retPing.tasks[tid])
return;
if(retPing.tasks[tid].pid)
{
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').removeClass("context-menu-item-disabled");
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').addClass("context-menu-item-disabled");
}
else
{
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').addClass("context-menu-item-disabled");
if(retPing.scheduler && retPing.scheduler.pid) if(retPing.scheduler && retPing.scheduler.pid)
{
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').removeClass("context-menu-item-disabled");
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').addClass("context-menu-item-disabled");
}
else
{
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').addClass("context-menu-item-disabled");
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').removeClass("context-menu-item-disabled"); $(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').removeClass("context-menu-item-disabled");
}
}
}
);
$('.task_manager .dropdown.task').contextMenu(
[
{
'Edit':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'edit'); },
title:'Modifier cette tache'
}
},
{
'Start':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'start'); },
title:'Demarrer cette tache'
}
},
{
'Stop':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'stop'); },
title:'Arreter cette tache'
}
},
{
'Delete':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'delete'); },
title:'Supprimer cette tache'
}
},
$.contextMenu.separator,
{
'Show log':
{
onclick:function(menuItem,menu) { doMenuTask($(this), 'log'); },
title:'Afficher les logs'
}
}
],
{
optionsIdx:{'edit':0, 'start':1, 'stop':2, 'delete':3, 'log':5},
doclick:function()
{
},
beforeShow:function()
{
var tid = $($(this)[0].target).parent().attr('id').split('_').pop();
if(!retPing || !retPing.tasks[tid])
return;
if(retPing.tasks[tid].pid)
{
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').removeClass("context-menu-item-disabled");
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').addClass("context-menu-item-disabled");
}
else else
{ $(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').addClass("context-menu-item-disabled");
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['stop']+')').addClass("context-menu-item-disabled");
if(retPing.scheduler && retPing.scheduler.pid)
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').removeClass("context-menu-item-disabled");
else
$(this.menu).find('.context-menu-item:eq('+this.optionsIdx['start']+')').addClass("context-menu-item-disabled");
}
} }
} }
); }
);
self.setTimeout("pingScheduler();", 100); self.setTimeout("pingScheduler(true);", 100); // true : loop forever each 2 sec
}) })
</script> </script>
</head> </head>
<body> <body>
@@ -461,58 +463,65 @@ foreach($tasks as $t)
<?php ?> <?php ?>
<script type="text/javascript"> <script type="text/javascript">
function editTask(tid) function editTask(tid)
{ {
document.forms["task"].target = ""; document.forms["task"].target = "";
document.forms["task"].act.value = "EDITTASK"; document.forms["task"].act.value = "EDITTASK";
document.forms["task"].tid.value = tid; document.forms["task"].tid.value = tid;
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({
function setSchedStatus(status) url: "/admin/adminFeedback.php",
{ data : {task_id:tid, action:"SETTASKSTATUS", status:status},
var url = "/admin/adminFeedback.php"; dataType:'xml',
url += "?action=SETSCHEDSTATUS&status=" + encodeURIComponent(status); success: function(ret)
$.ajax({
url: url,
dataType:'xml',
success: function(ret)
{
}
});
}
function deleteTask(tid)
{
if(confirm("<?php echo p4string::MakeString(_('admin::tasks: supprimer la tache ?'), 'js', '"') ?>"))
{ {
document.forms["taskManager"].target = ""; pingScheduler(false); // false : just one time
document.forms["taskManager"].act.value = "DELETETASK";
document.forms["taskManager"].tid.value = tid;
document.forms["taskManager"].submit();
} }
} });
}
function setSchedStatus(status)
{
$.ajax({
url: "/admin/adminFeedback.php",
data : { action:"SETSCHEDSTATUS", status:status },
dataType:'xml',
success: function(ret)
{
pingScheduler(false); // false : just one time
}
});
}
function deleteTask(tid)
{
if(confirm("<?php echo p4string::MakeString(_('admin::tasks: supprimer la tache ?'), 'js', '"') ?>"))
{
document.forms["taskManager"].target = "";
document.forms["taskManager"].act.value = "DELETETASK";
document.forms["taskManager"].tid.value = tid;
document.forms["taskManager"].submit();
}
}
/*
function old_pingScheduler() function old_pingScheduler()
{ {
$.ajax({ $.ajax({
@@ -652,59 +661,75 @@ 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',
dataType:'json', dataType:'json',
success: function(ret) success: function(ret)
{
retPing = ret; // global
$("#pingTime").empty().append(ret.time);
if(ret.scheduler)
{ {
retPing = ret; // global if(ret.scheduler.status)
$("#pingTime").empty().append(ret.time); $("#STATUS_SCHED").html(ret.scheduler.status);
if(ret.scheduler && ret.scheduler.pid) else
{ $("#STATUS_SCHED").html('');
$("#PID_SCHED").html(ret.scheduler.pid); if(ret.scheduler.pid)
} $("#PID_SCHED").html(ret.scheduler.pid);
else else
{
$("#PID_SCHED").html('-'); $("#PID_SCHED").html('-');
} }
if(ret.tasks) else
{
$("#STATUS_SCHED").html('');
$("#PID_SCHED").html('-');
}
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)
$("#PID_"+id).html(ret.tasks[id].pid);
else
$("#PID_"+id).html('-');
if(ret.tasks[id].completed && ret.tasks[id].completed>0 && ret.tasks[id].completed<=100)
{ {
if(ret.tasks[id].pid) $("#COMP_"+id).width(ret.tasks[id].completed + "%");
$("#PID_"+id).html(ret.tasks[id].pid); $("#COMPBOX_"+id).show();
else }
$("#PID_"+id).html('-'); else
if(ret.tasks[id].completed && ret.tasks[id].completed>0 && ret.tasks[id].completed<=100) {
{ $("#COMPBOX_"+id).hide();
$("#COMP_"+id).width(ret.tasks[id].completed + "%"); $("#COMP_"+id).width('0px');
$("#COMPBOX_"+id).show();
}
else
{
$("#COMPBOX_"+id).hide();
$("#COMP_"+id).width('0px');
}
} }
} }
self.setTimeout("pingScheduler();", 3000);
} }
}); if(repeat)
} self.setTimeout("pingScheduler(true);", 1000);
}
});
}
function lauchScheduler() function lauchScheduler()
{ {
url = "./runscheduler.php"; url = "./runscheduler.php";
document.getElementById("zsched").src = url; document.getElementById("zsched").src = url;
self.setTimeout('document.getElementById("zsched").src="about:blank";', 2000); self.setTimeout('document.getElementById("zsched").src="about:blank";', 2000);
} }
</script> </script>