Refactored main components

This commit is contained in:
Paolo
2026-06-23 14:59:34 +02:00
parent 8126665acd
commit c40ee917df
4 changed files with 209 additions and 101 deletions
@@ -38,7 +38,8 @@ class LongRunTaskExecJob extends JOB_Controller
$this->logInfo('Execute long run tasks started');
// Get all the LRTs that is possible to execute now
$lrtsResult = $this->longruntasklib->getLRTs();
$lrtsResult = $this->longruntasklib->getNewLRTs();
// If an error occurred then return it
if (isError($lrtsResult)) return $lrtsResult;
if (hasData($lrtsResult))
@@ -47,7 +48,8 @@ class LongRunTaskExecJob extends JOB_Controller
foreach (getData($lrtsResult) as $lrt)
{
// Execute the task
$this->longruntasklib->executeLrt($lrt);
$executeLrtResult = $this->longruntasklib->executeLrt($lrt);
if (isError($executeLrtResult)) $this->logError($executeLrtResult);
}
}
@@ -55,7 +57,7 @@ class LongRunTaskExecJob extends JOB_Controller
}
/**
*
* Kills all the hanging LRTs
*/
public function killHangingLRTs()
{
@@ -63,6 +65,7 @@ class LongRunTaskExecJob extends JOB_Controller
// Get all the LRTs that is possible to execute now
$lrtsResult = $this->longruntasklib->getHangingLRTs();
// If an error occurred then return it
if (isError($lrtsResult)) return $lrtsResult;
if (hasData($lrtsResult))
@@ -70,16 +73,40 @@ class LongRunTaskExecJob extends JOB_Controller
// For each LRT
foreach (getData($lrtsResult) as $lrt)
{
// Kill the process with a SIGKILL
exec('kill -9 '.$lrt->pid.' > /dev/null 2>&1');
// Set the LRT as failed
$lrtExecFailedResult = $this->longruntasklib->lrtExecFailed($lrt->jobid);
if (isError($lrtExecFailedResult)) $this->logError(getError(lrtExecFailedResult));
// Kill the task
$killLrtResult = $this->longruntasklib->killLrt($lrt);
if (isError($killLrtResult)) $this->logError($killLrtResult);
}
}
$this->logInfo('Kill hanging LRTs ended');
}
/**
*
*/
public function checkExecution()
{
$this->logInfo('Check execution long run tasks started');
// Get the related LRT data from the queue
$lrtsResult = $this->longruntasklib->getRunningLRTs();
// If an error occurred then return it
if (isError($lrtsResult)) return $lrtsResult;
// If there are running LRTs
if (hasData($lrtsResult))
{
// For each LRT
foreach (getData($lrtsResult) as $lrt)
{
// Check the LRT execution
$checkExecutionResult = $this->longruntasklib->checkExecution($lrt);
if (isError($checkExecutionResult)) $this->logError($checkExecutionResult);
}
}
$this->logInfo('Check execution long run tasks ended');
}
}
+61 -56
View File
@@ -9,69 +9,74 @@ 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
* This method must be implemented!
*/
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();
// If an error occurred or the record has not been found
if (isError($lrtResult) || !hasData($lrtResult))
{
$this->logError($lrtResult);
}
else
{
// Get the record
$lrt = getData($lrtResult)[0];
// Get and check the input
$input = json_decode($lrt->input);
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((($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('The user '.$lrt->uid.' slept for '.$input->sleep.' seconds');
if (isError($setOutputResult))
{
$this->logError($setOutputResult);
}
}
}
}
$this->_doIt($jobid);
$this->logInfo('Long run tasks '.get_class($this).' ended');
}
/**
* Loops on the number of seconds provided by the LRT input
* Sleeps every time 1 sec
* Writes the progress
* Writes the output
*/
private function _doIt($jobid)
{
// Get the LRT record related to the provided jobid
$lrtResult = $this->getLrt($jobid);
// If an error occurred or the record has not been found
if (isError($lrtResult))
{
$this->logError($lrtResult);
return;
}
if (!hasData($lrtResult))
{
$this->logError('LRT not found in database');
return;
}
// Get the record
$lrt = getData($lrtResult)[0];
// Get and check the input
$input = json_decode($lrt->{LongRunTaskLib::PROPERTY_INPUT});
if ($input == null)
{
$this->logError('LRT input is not a valid json');
return;
}
// 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);
return;
}
}
$sleepMsg = 'The user '.$lrt->{LongRunTaskLib::PROPERTY_UID}.' slept for '.$input->sleep.' seconds';
$this->logInfo($sleepMsg);
// Set the output
$setOutputResult = $this->setOutput($jobid, $sleepMsg);
if (isError($setOutputResult))
{
$this->logError($setOutputResult);
}
}
}
+6 -23
View File
@@ -15,8 +15,6 @@ if (!defined("BASEPATH")) exit("No direct script access allowed");
*/
abstract class LRT_Controller extends JOB_Controller
{
protected $_jobid; // record id for this LRT
/**
* Constructor
*/
@@ -34,21 +32,6 @@ abstract class LRT_Controller extends JOB_Controller
// Loads LongRunTaskLib library
$this->load->library('LongRunTaskLib');
$this->_jobid = null; // default value
}
/**
* Destructor, once the LRT execution is over...
*/
public function __destruct()
{
// Sends email to the user
// Set the status and the endtime of this LRT as done
$lrtExecOverResult = $this->longruntasklib->lrtExecOver($this->_jobid);
// If an error occurred then log it
if (isError($lrtExecOverResult)) $this->logError($lrtExecOverResult);
}
//------------------------------------------------------------------------------------------------------------------
@@ -62,25 +45,25 @@ abstract class LRT_Controller extends JOB_Controller
/**
*
*/
protected function getLrt()
protected function getLrt($jobid)
{
return $this->longruntasklib->getLrt($this->_jobid);
return $this->longruntasklib->getLrt($jobid);
}
/**
*
*/
protected function setProgress($progress)
protected function setProgress($jobid, $progress)
{
return $this->longruntasklib->setProgress($this->_jobid, $progress);
return $this->longruntasklib->setProgress($jobid, $progress);
}
/**
*
*/
protected function setOutput($output)
protected function setOutput($jobid, $output)
{
return $this->longruntasklib->setOutuput($this->_jobid, $output);
return $this->longruntasklib->setOutuput($jobid, $output);
}
}
+106 -13
View File
@@ -17,6 +17,7 @@ class LongRunTaskLib extends JobsQueueLib
// LRT object properties
const PROPERTY_UID = 'uid';
const PROPERTY_PID = 'pid';
/**
* Constructor
@@ -37,7 +38,7 @@ class LongRunTaskLib extends JobsQueueLib
* The maximum number of returned queued LRTs is limited by:
* number of currently running LRTs - maximum allowed number of LRTs for the system
*/
public function getLRTs()
public function getNewLRTs()
{
// Get all the running LRTs
$runningLrtsResult = $this->getJobsByTypeStatus($this->_ci->config->item(self::CFG_LRT_TYPES), JobsQueueLib::STATUS_RUNNING);
@@ -71,6 +72,25 @@ class LongRunTaskLib extends JobsQueueLib
);
}
/**
* Get all the LRT that are currently running
*/
public function getRunningLRTs()
{
// 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(
$this->_ci->config->item(self::CFG_LRT_TYPES),
JobsQueueLib::STATUS_RUNNING
)
);
}
/**
* Execute a LRT in background
* - Checks if the wanted LRT exists in the applcation/controllers/lrts directory
@@ -90,7 +110,12 @@ 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}.' > /dev/null 2>&1 & echo $!',
sprintf(
'/usr/bin/php %s/../index.ci.php lrts/%s/run %s > /dev/null 2>&1 & echo $!',
APPPATH,
$lrt->{self::PROPERTY_TYPE},
$lrt->{self::PROPERTY_JOBID}
),
$output // Here goes the output from the standard output and error
);
@@ -110,17 +135,78 @@ class LongRunTaskLib extends JobsQueueLib
}
/**
* Set the LRT in the queue as failed
* Kill the provided LRT
* To avoid to kill a process that is not this LRT,
* since the same PID can be assigned to another process once this ended
*/
public function lrtExecFailed($jobid)
public function killLrt($lrt)
{
return $this->_ci->JobsQueueModel->update(
$jobid,
// Try to get the pid of this LRT from the system
$pid = exec(
sprintf(
'ps -eo pid,cmd | grep "index.ci.php lrts/%s/run %s" | grep -v grep | awk \'{print $1}\'',
$lrt->{self::PROPERTY_TYPE},
$lrt->{self::PROPERTY_JOBID}
)
);
// If the pid is the same then kill the process with a SIGKILL
if ($pid == $lrt->{self::PROPERTY_PID}) exec('kill -9 '.$lrt->{self::PROPERTY_PID}.' > /dev/null 2>&1');
// Set the LRT as failed in any case
$lrtExecFailedResult = $this->_ci->JobsQueueModel->update(
$lrt->{self::PROPERTY_JOBID},
array(
'endtime' => 'NOW()',
'status' => self::STATUS_FAILED
)
);
// If an error occurred then return it
if (isError($lrtExecFailedResult)) return $lrtExecFailedResult;
}
/**
*
*/
public function checkExecution($lrt)
{
// If the LRT stopped running
if (!$this->_isRunning($lrt))
{
// Loads MessageLib library
$this->_ci->load->library('MessageLib');
// Load the BenutzerModel
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
// Get the benutzer for this uid
$benutzerResult = $this->_ci->BenutzerModel->loadWhere(array('uid' => $lrt->{LongRunTaskLib::PROPERTY_UID}));
// If an error occurred then return it
if (isError($benutzerResult)) return $benutzerResult;
// If no benutzer has been found
if (!hasData($benutzerResult)) return error('No benutzer found, uid: '.$lrt->{LongRunTaskLib::PROPERTY_UID});
$benutzer = getData($benutzerResult)[0];
// Sends a message to the user
$messageResult = $this->_ci->messagelib->sendMessageUser(
$benutzer->person_id,
'Long run task ended',
'The long run task '.$lrt->{self::PROPERTY_TYPE}.' ended, output: '.$lrt->{self::PROPERTY_OUTPUT}
);
// If an error occurred then return it
if (isError($messageResult)) return $messageResult;
// Set the LRT as done
$lrtExecOverResult = $this->_ci->JobsQueueModel->update(
$lrt->{self::PROPERTY_JOBID},
array(
'endtime' => 'NOW()',
'status' => self::STATUS_DONE
)
);
// If an error occurred then return it
if (isError($lrtExecOverResult)) return $lrtExecOverResult;
}
}
//------------------------------------------------------------------------------------------------------------------
@@ -222,18 +308,25 @@ class LongRunTaskLib extends JobsQueueLib
return $this->_ci->JobsQueueModel->update($jobid, array('output' => json_encode($output)));
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Set the LRT in the queue as successfully ended
* Return true if the LRT is still running
*/
public function lrtExecOver($jobid)
private function _isRunning($lrt)
{
return $this->_ci->JobsQueueModel->update(
$jobid,
array(
'endtime' => 'NOW()',
'status' => self::STATUS_DONE
// Try to get the pid of this LRT from the system
$pid = exec(
sprintf(
'ps -eo pid,cmd | grep "index.ci.php lrts/%s/run %s" | grep -v grep | awk \'{print $1}\'',
$lrt->{self::PROPERTY_TYPE},
$lrt->{self::PROPERTY_JOBID}
)
);
// If the pid is the same then the LRT is still running
return $pid == $lrt->{self::PROPERTY_PID};
}
}