mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-24 07:29:28 +00:00
Refactored main components
This commit is contained in:
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user