diff --git a/application/controllers/jobs/LongRunTaskExecJob.php b/application/controllers/jobs/LongRunTaskExecJob.php index f4bcfb5cf..5493dc205 100644 --- a/application/controllers/jobs/LongRunTaskExecJob.php +++ b/application/controllers/jobs/LongRunTaskExecJob.php @@ -31,7 +31,7 @@ class LongRunTaskExecJob extends JQW_Controller } /** - * + * Executes all the new LRTs */ public function execEmAll() { @@ -41,13 +41,14 @@ class LongRunTaskExecJob extends JQW_Controller $lrtsResult = $this->longruntasklib->getLRTs(); if (isError($lrtsResult)) return $lrtsResult; - // For each LRT - foreach (getData($lrtsResult) as $lrt) + if (hasData($lrtsResult)) { - // Execute the task - $execResult = $this->longruntasklib->executeLrt($lrt); - // If an error occurred log it and continue with the next one - if (isError($execResult)) $this->logError(getError($execResult)); + // For each LRT + foreach (getData($lrtsResult) as $lrt) + { + // Execute the task + $this->longruntasklib->executeLrt($lrt); + } } $this->logInfo('Execute long run tasks ended'); diff --git a/application/controllers/lrts/LRTDummy.php b/application/controllers/lrts/LRTDummy.php index 88e4a383f..fdbfe7a93 100644 --- a/application/controllers/lrts/LRTDummy.php +++ b/application/controllers/lrts/LRTDummy.php @@ -9,26 +9,69 @@ if (!defined("BASEPATH")) exit("No direct script access allowed"); class LRTDummy extends LRT_Controller { /** - * + * Loops on the number of seconds provided by the LRT input + * Sleeps every time 1 sec + * Writes the progress + * Writes the output */ public function run($jobid) { + $this->logInfo('Long run tasks '.get_class($this).' started'); + + $this->_jobid = $jobid; + // Get the LRT record related to the provided jobid $lrtResult = $this->getLrt($jobid); - // If an error occurred or a record has not been found + // If an error occurred or the record has not been found if (isError($lrtResult) || !hasData($lrtResult)) { - $this->logError(getError($lrtResult)); + $this->logError($lrtResult); } else { + // Get the record $lrt = getData($lrtResult)[0]; + + // Get and check the input $input = json_decode($lrt->input); - sleep((int)$input->sleep); - $this->setProgress($jobid, 100); - $this->setOutput($jobid, 'I slept for '.$input->sleep.' seconds'); + if ($input == null) + { + $this->logError('LRT input is not a valid json'); + } + else + { + $error = false; // be optimistic + + // Operation + for ($i = 0; $i < (int)$input->sleep; $i++) + { + sleep(1); + // Set the progress + $setProgressResult = $this->setProgress($jobid, (($i + 1) / (int)$input->sleep) * 100); + if (isError($setProgressResult)) + { + $this->logError($setProgressResult); + $error = true; + } + } + + // If no errors + if (!$error) + { + $this->logInfo('The user '.$lrt->uid.' slept for '.$input->sleep.' seconds'); + + // Set the output + $setOutputResult = $this->setOutput($jobid, 'The user '.$lrt->uid.' slept for '.$input->sleep.' seconds'); + if (isError($setOutputResult)) + { + $this->logError($setOutputResult); + } + } + } } + + $this->logInfo('Long run tasks '.get_class($this).' ended'); } } diff --git a/application/core/LRT_Controller.php b/application/core/LRT_Controller.php index 3b2aebe40..357f981b9 100644 --- a/application/core/LRT_Controller.php +++ b/application/core/LRT_Controller.php @@ -15,6 +15,8 @@ if (!defined("BASEPATH")) exit("No direct script access allowed"); */ abstract class LRT_Controller extends JQW_Controller { + protected $_jobid; // record id for this LRT + /** * Constructor */ @@ -32,6 +34,29 @@ abstract class LRT_Controller extends JQW_Controller // Loads LongRunTaskLib library $this->load->library('LongRunTaskLib'); + + $this->_jobid = null; // default value + } + + /** + * Destructor, once the LRT execution is over... + */ + public function __destruct() + { + // Check if the property has been set + if ($this->_jobid == null) + { + $this->logError( + 'The method '.get_class($this).'->run must assign the value of the jobid parameter to the property _jobid at the very beginning: $this->_jobid = $jobid;' + ); + } + else // If set then + { + // Set the status of this LRT as done + $setStatusResult = $this->longruntasklib->setStatus($this->_jobid, LongRunTaskLib::STATUS_DONE); + // If an error occurred then log it + if (isError($setStatusResult)) $this->logError($setStatusResult); + } } //------------------------------------------------------------------------------------------------------------------ @@ -47,7 +72,7 @@ abstract class LRT_Controller extends JQW_Controller */ protected function getLrt($jobid) { - $this->longruntasklib->getLrt($jobid); + return $this->longruntasklib->getLrt($jobid); } /** @@ -55,15 +80,15 @@ abstract class LRT_Controller extends JQW_Controller */ protected function setProgress($jobid, $progress) { - $this->longruntasklib->setProgress($jobid, $progress); + return $this->longruntasklib->setProgress($jobid, $progress); } /** * */ - protected function setOutuput($jobid, $output) + protected function setOutput($jobid, $output) { - $this->longruntasklib->setOutuput($jobid, $output); + return $this->longruntasklib->setOutuput($jobid, $output); } } diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index cca22a9e1..96e086b7f 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -64,14 +64,29 @@ class JobsQueueLib */ public function getOldestJobs($type, $maxAmount = null) { - $this->_ci->JobsQueueModel->resetQuery(); - - $this->_ci->JobsQueueModel->addOrder('creationtime', 'ASC'); + $types = $type; // default is array + $limit = 0; // default query limit // If the maximum amount of jobs to retrieve have been specified - if (is_numeric($maxAmount)) $this->_ci->JobsQueueModel->addLimit($maxAmount); + if (is_numeric($maxAmount)) $limit = $maxAmount; - return $this->_ci->JobsQueueModel->loadWhere(array('status' => self::STATUS_NEW, 'type' => $type)); + // If it is a string then include it into an array + if (!isEmptyString($type) && is_string($type)) $types = array($type); + + // Return the result of the query + return $this->_ci->JobsQueueModel->execReadOnlyQuery(' + SELECT jq.* + FROM system.tbl_jobsqueue jq + WHERE jq.type IN ? + AND jq.status = ? + ORDER BY jq.creationtime DESC + LIMIT ?', + array( + $types, + self::STATUS_NEW, + $limit + ) + ); } /** @@ -79,11 +94,23 @@ class JobsQueueLib */ public function getJobsByTypeStatus($type, $status) { - $this->_ci->JobsQueueModel->resetQuery(); + $types = $type; // default is array - $this->_ci->JobsQueueModel->addOrder('creationtime', 'DESC'); + // If it is a string then include it into an array + if (!isEmptyString($type) && is_string($type)) $types = array($type); - return $this->_ci->JobsQueueModel->loadWhere(array('status' => $status, 'type' => $type)); + // Return the result of the query + return $this->_ci->JobsQueueModel->execReadOnlyQuery(' + SELECT jq.* + FROM system.tbl_jobsqueue jq + WHERE jq.type IN ? + AND jq.status = ? + ORDER BY jq.creationtime DESC', + array( + $types, + $status + ) + ); } /** diff --git a/application/libraries/LongRunTaskLib.php b/application/libraries/LongRunTaskLib.php index 78c020055..1827bfb25 100644 --- a/application/libraries/LongRunTaskLib.php +++ b/application/libraries/LongRunTaskLib.php @@ -50,12 +50,18 @@ class LongRunTaskLib extends JobsQueueLib } /** - * + * Execute a LRT in background + * - Checks if the wanted LRT exists in the applcation/controllers/lrts directory + * - Then executes it in background via CI CLI + * - Stores the LRT pid into the database */ public function executeLrt($lrt) { + $output = array(); + $return_var = -1; + // If does _not_ exist a LRT implementation for this LRT type, then return an error - if ((include_once 'application/controllers/lrts/'.$lrt->{self::PROPERTY_TYPE}.'.php') !== true) + if (!file_exists(APPPATH.'controllers/lrts/'.$lrt->{self::PROPERTY_TYPE}.'.php')) { return error('The required LRT implementation has not been found'); } @@ -63,10 +69,17 @@ class LongRunTaskLib extends JobsQueueLib // Execute the LRT implementation (a CI controller from CLI) providing as parameter the jobid exec( // Command - '/usr/bin/php '.APPPATH.'../index.ci.php lrts/'.$lrt->{self::PROPERTY_TYPE}.'/run '.$lrt->{self::PROPERTY_JOBID}.' &', + '/usr/bin/php '.APPPATH.'../index.ci.php lrts/'.$lrt->{self::PROPERTY_TYPE}.'/run '.$lrt->{self::PROPERTY_JOBID}.' > /dev/null 2>&1 & echo $!', $output, // Here goes the output from the standard output and error $return_var // Status of the command once executed (== 0 success, !=0 error) ); + + // If a pid has not been returned + if (isEmptyArray($output) || !is_numeric($output[0])) return error('Not a valid pid has been returned'); + + // Set the pid of this LRT into the database + $pidResult = $this->_ci->JobsQueueModel->update($lrt->{self::PROPERTY_JOBID}, array('pid' => $output[0])); + if (isError($pidResult)) return $pidResult; } //------------------------------------------------------------------------------------------------------------------ @@ -142,5 +155,13 @@ class LongRunTaskLib extends JobsQueueLib { return $this->_ci->JobsQueueModel->update($jobid, array('output' => json_encode($output))); } + + /** + * + */ + public function setStatus($jobid, $status) + { + return $this->_ci->JobsQueueModel->update($jobid, array('status' => $status)); + } }