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

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,8 @@ abstract class task_abstract
const STATE_MAXMEGSREACHED = 'STATE_MAXMEGS';
const STATE_MAXRECSDONE = 'STATE_MAXRECS';
const STATE_FINISHED = 'STATE_FINISHED';
const SIGNAL_SCHEDULER_DIED = 'SIGNAL_SCHEDULER_DIED';
protected $suicidable = false;
protected $launched_by = 0;
@@ -129,7 +131,7 @@ abstract class task_abstract
, self::RETURNSTATUS_TORESTART
, self::STATUS_TOSTART
);
if (!in_array($status, $av_status))
if(!in_array($status, $av_status))
throw new Exception(sprintf('unknown status `%s`', $status));
@@ -145,18 +147,17 @@ abstract class task_abstract
return $this->task_status;
}
public function set_pid($pid)
{
$conn = connection::getPDOConnection();
$sql = 'UPDATE task2 SET pid = :pid WHERE task_id = :taskid';
$stmt = $conn->prepare($sql);
$stmt->execute(array(':pid' => $pid, ':taskid' => $this->get_task_id()));
$stmt->closeCursor();
return $this;
}
// public function set_pid($pid)
// {
// $conn = connection::getPDOConnection();
//
// $sql = 'UPDATE task2 SET pid = :pid WHERE task_id = :taskid';
// $stmt = $conn->prepare($sql);
// $stmt->execute(array(':pid' => $pid, ':taskid' => $this->get_task_id()));
// $stmt->closeCursor();
//
// return $this;
// }
// 'active' means 'auto-start when scheduler starts'
public function set_active($boolean)
{
@@ -221,6 +222,7 @@ abstract class task_abstract
{
return $this->crash_counter;
}
public function increment_crash_counter()
{
$conn = connection::getPDOConnection();
@@ -268,9 +270,9 @@ abstract class task_abstract
$this->system = system_server::get_platform();
$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");
flush();
@@ -279,7 +281,7 @@ abstract class task_abstract
}
else
{
if ($this->launched_by == self::LAUCHED_BY_COMMANDLINE)
if($this->launched_by == self::LAUCHED_BY_COMMANDLINE)
{
flush();
}
@@ -289,11 +291,14 @@ abstract class task_abstract
{
$conn = connection::getPDOConnection();
}
catch (Exception $e)
catch(Exception $e)
{
$this->log($e->getMessage());
$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;
return('');
@@ -304,7 +309,7 @@ abstract class task_abstract
$stmt->execute(array(':taskid' => $this->get_task_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row)
if(!$row)
throw new Exception('Unknown task id');
$this->title = $row['name'];
$this->crash_counter = (int) $row['crashed'];
@@ -357,7 +362,7 @@ abstract class task_abstract
$stmt->closeCursor();
$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);
return;
@@ -366,7 +371,7 @@ abstract class task_abstract
protected function check_memory_usage()
{
$current_memory = memory_get_usage();
if ($current_memory >> 20 >= $this->maxmegs)
if($current_memory >> 20 >= $this->maxmegs)
{
$this->log(sprintf(
"Max memory (%s M) reached (current is %s M)"
@@ -381,7 +386,7 @@ abstract class task_abstract
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;
}
@@ -402,26 +407,68 @@ abstract class task_abstract
public function get_pid()
{
$conn = connection::getPDOConnection();
$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 = NULL;
$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;
}
/*
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()
{
switch ($this->current_state)
switch($this->current_state)
{
case self::STATE_MAXMEGSREACHED:
case self::STATE_MAXRECSDONE:
default:
if ($this->get_runner() == self::RUNNER_SCHEDULER)
if($this->get_runner() == self::RUNNER_SCHEDULER)
{
$this->task_status = self::STATUS_TOSTOP;
$this->return_value = self::RETURNSTATUS_TORESTART;
@@ -429,7 +476,7 @@ abstract class task_abstract
break;
case self::STATE_FINISHED:
$this->task_status = self::STATUS_TOSTOP;
if ($this->suicidable === true)
if($this->suicidable === true)
{
$this->return_value = self::RETURNSTATUS_TODELETE;
$this->log('will hang myself');
@@ -458,13 +505,13 @@ abstract class task_abstract
$stmt->execute(array(':taskid' => $this->get_task_id()));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
if (!$row || $row['status'] == 'tostop')
if(!$row || $row['status'] == 'tostop')
{
$this->task_status = self::STATUS_TOSTOP;
$this->return_value = self::RETURNSTATUS_STOPPED;
}
}
catch (Exception $e)
catch(Exception $e)
{
$this->return_value = self::RETURNSTATUS_STOPPED;
$this->task_status = self::STATUS_TOSTOP;
@@ -477,21 +524,26 @@ abstract class task_abstract
protected function pause($when_started=0)
{
$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;
if ($when_started < $this->period)
if($when_started < $this->period)
{
$conn = connection::getPDOConnection();
$conn->close();
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)
{
// ************************************************
// 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();
$conn = connection::getPDOConnection();
@@ -499,8 +551,10 @@ abstract class task_abstract
system_file::mkdir($lockdir = $registry->get('GV_RootPath') . 'tmp/locks/');
$locker = true;
$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);
fclose($tasklock);
@@ -511,6 +565,8 @@ abstract class task_abstract
ftruncate($tasklock, 0);
fwrite($tasklock, '' . getmypid());
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);
@@ -526,7 +582,7 @@ abstract class task_abstract
fclose($tasklock);
@unlink($lockfile);
if ($this->return_value == self::RETURNSTATUS_TODELETE)
if($this->return_value == self::RETURNSTATUS_TODELETE)
$this->delete();
else
$this->set_status($this->return_value);
@@ -536,42 +592,20 @@ abstract class task_abstract
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)
{
$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->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->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->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;
return $this;
@@ -579,7 +613,7 @@ abstract class task_abstract
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->task_status = self::STATUS_TOSTOP;
@@ -593,7 +627,7 @@ abstract class task_abstract
public function apply_task_status()
{
if ($this->task_status == self::STATUS_TOSTOP)
if($this->task_status == self::STATUS_TOSTOP)
{
$this->running = false;
}
@@ -605,7 +639,7 @@ abstract class task_abstract
{
static $lastt = null;
$t = explode(' ', ($ut = microtime()));
if ($lastt === null)
if($lastt === null)
$lastt = $t;
$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)
{
if (!class_exists($class_name))
if(!class_exists($class_name))
throw new Exception('Unknown task class');
$sql = 'INSERT INTO task2
@@ -649,9 +683,9 @@ abstract class task_abstract
:name, "0000/00/00 00:00:00", :class, :settings)';
if ($settings && !DOMDocument::loadXML($settings))
if($settings && !DOMDocument::loadXML($settings))
throw new Exception('settings invalide');
elseif (!$settings)
elseif(!$settings)
$settings = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tasksettings>\n</tasksettings>";
$params = array(
@@ -673,7 +707,7 @@ abstract class task_abstract
{
global $argc, $argv;
$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";
return($t);
@@ -704,9 +738,9 @@ abstract class task_abstract
$stmt->closeCursor();
$this->completed_percentage = $p;
}
catch (Exception $e)
catch(Exception $e)
{
}
return $this;

View File

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

View File

@@ -90,34 +90,26 @@ class task_manager
continue;
try
{
if( ($lock = fopen( $lockdir . 'task.'.$row['task_id'].'.lock', 'a+')) )
{
if (flock($lock, LOCK_SH | LOCK_NB) === FALSE)
{
// already locked : running !
$row['pid'] = fgets($lock, 512);
}
else
{
// can lock : not running
flock($lock, LOCK_UN);
}
fclose($lock);
}
// if( ($lock = fopen( $lockdir . 'task.'.$row['task_id'].'.lock', 'a+')) )
// {
// if (flock($lock, LOCK_SH | LOCK_NB) === FALSE)
// {
// // already locked : running !
// $row['pid'] = fgets($lock, 512);
// }
// else
// {
// // can lock : not running
// flock($lock, LOCK_UN);
// }
// fclose($lock);
// }
$tasks[$row['task_id']] = new $classname($row['task_id']);
}
catch (Exception $e)
{
}
}
$this->tasks = $tasks;
@@ -175,8 +167,13 @@ class task_manager
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();
$lockdir = $appbox->get_registry()->get('GV_RootPath') . 'tmp/locks/';
if( ($schedlock = fopen( $lockdir . 'scheduler.lock', 'a+')) )
@@ -184,12 +181,6 @@ class task_manager
if (flock($schedlock, LOCK_SH | LOCK_NB) === FALSE)
{
// 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);
}
else