Merge branch 'pid' into hotfix/5.0.4
This commit is contained in:
@@ -186,6 +186,7 @@ class CronManager
|
||||
}
|
||||
|
||||
$job->set('status', self::RUNNING);
|
||||
$job->set('pid', $this->getCronJobUtil()->getPid());
|
||||
$this->getEntityManager()->saveEntity($job);
|
||||
$this->getEntityManager()->getPdo()->query('UNLOCK TABLES');
|
||||
|
||||
|
||||
@@ -28,10 +28,11 @@
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Utils\Cron;
|
||||
use \PDO;
|
||||
use \Espo\Core\CronManager;
|
||||
use \Espo\Core\Utils\Config;
|
||||
use \Espo\Core\ORM\EntityManager;
|
||||
|
||||
use PDO;
|
||||
use Espo\Core\CronManager;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\ORM\EntityManager;
|
||||
|
||||
class Job
|
||||
{
|
||||
@@ -41,12 +42,15 @@ class Job
|
||||
|
||||
private $cronScheduledJob;
|
||||
|
||||
private $systemUtils;
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
|
||||
$this->cronScheduledJob = new ScheduledJob($this->config, $this->entityManager);
|
||||
$this->systemUtils = new \Espo\Core\Utils\System();
|
||||
}
|
||||
|
||||
protected function getConfig()
|
||||
@@ -64,6 +68,11 @@ class Job
|
||||
return $this->cronScheduledJob;
|
||||
}
|
||||
|
||||
protected function getSystemUtils()
|
||||
{
|
||||
return $this->systemUtils;
|
||||
}
|
||||
|
||||
public function isJobPending($id)
|
||||
{
|
||||
return !!$this->getEntityManager()->getRepository('Job')->select(['id'])->where([
|
||||
@@ -181,37 +190,58 @@ class Job
|
||||
*/
|
||||
public function markFailedJobs()
|
||||
{
|
||||
$currentTime = time();
|
||||
$periodTime = $currentTime - intval($this->getConfig()->get('jobPeriod', 0));
|
||||
$this->markFailedJobsByPeriod('jobPeriodForActiveProcess');
|
||||
$this->markFailedJobsByPeriod('jobPeriod');
|
||||
}
|
||||
|
||||
protected function markFailedJobsByPeriod($period)
|
||||
{
|
||||
$time = time() - $this->getConfig()->get($period);
|
||||
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
|
||||
$select = "
|
||||
SELECT id, scheduled_job_id, execute_time, target_id, target_type FROM `job`
|
||||
SELECT id, scheduled_job_id, execute_time, target_id, target_type, pid FROM `job`
|
||||
WHERE
|
||||
`status` = '" . CronManager::RUNNING ."' AND execute_time < '".date('Y-m-d H:i:s', $periodTime)."'
|
||||
`status` = '" . CronManager::RUNNING ."' AND execute_time < '".date('Y-m-d H:i:s', $time)."'
|
||||
";
|
||||
$sth = $pdo->prepare($select);
|
||||
$sth->execute();
|
||||
|
||||
$jobData = array();
|
||||
while ($row = $sth->fetch(PDO::FETCH_ASSOC)){
|
||||
$jobData[$row['id']] = $row;
|
||||
|
||||
switch ($period) {
|
||||
case 'jobPeriod':
|
||||
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
|
||||
if (!$this->getSystemUtils()->isProcessActive($row['pid'])) {
|
||||
$jobData[$row['id']] = $row;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'jobPeriodForActiveProcess':
|
||||
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
|
||||
$jobData[$row['id']] = $row;
|
||||
}
|
||||
$additionalSetQuery = ", attempts = 0";
|
||||
break;
|
||||
}
|
||||
|
||||
$update = "
|
||||
UPDATE job
|
||||
SET `status` = '". CronManager::FAILED ."'
|
||||
WHERE id IN ('".implode("', '", array_keys($jobData))."')
|
||||
";
|
||||
$sth = $pdo->prepare($update);
|
||||
$sth->execute();
|
||||
if (!empty($jobData)) {
|
||||
$update = "
|
||||
UPDATE job
|
||||
SET `status` = '" . CronManager::FAILED . "'" . (isset($additionalSetQuery) ? $additionalSetQuery : "") . "
|
||||
WHERE id IN ('".implode("', '", array_keys($jobData))."')
|
||||
";
|
||||
$sth = $pdo->prepare($update);
|
||||
$sth->execute();
|
||||
|
||||
//add status 'Failed' to SchediledJobLog
|
||||
$cronScheduledJob = $this->getCronScheduledJob();
|
||||
foreach ($jobData as $jobId => $job) {
|
||||
if (!empty($job['scheduled_job_id'])) {
|
||||
$cronScheduledJob->addLogRecord($job['scheduled_job_id'], CronManager::FAILED, $job['execute_time'], $job['target_id'], $job['target_type']);
|
||||
//add status 'Failed' to SchediledJobLog
|
||||
$cronScheduledJob = $this->getCronScheduledJob();
|
||||
foreach ($jobData as $jobId => $job) {
|
||||
if (!empty($job['scheduled_job_id'])) {
|
||||
$cronScheduledJob->addLogRecord($job['scheduled_job_id'], CronManager::FAILED, $job['execute_time'], $job['target_id'], $job['target_type']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,4 +343,9 @@ class Job
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getPid()
|
||||
{
|
||||
return $this->getSystemUtils()->getPid();
|
||||
}
|
||||
}
|
||||
@@ -134,4 +134,38 @@ class System
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pet process ID
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getPid()
|
||||
{
|
||||
return getmypid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if process is active
|
||||
*
|
||||
* @param integer $pid
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isProcessActive($pid)
|
||||
{
|
||||
if (empty($pid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('posix_getsid')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (posix_getsid($pid) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ return array ( 'defaultPermissions' =>
|
||||
),
|
||||
'jobMaxPortion' => 15, /** Max number of jobs per one execution. */
|
||||
'jobPeriod' => 7800, /** Max execution time (in seconds) allocated for a sinle job. If exceeded then set to Failed.*/
|
||||
'jobPeriodForActiveProcess' => 36000, /** Max execution time (in seconds) allocated for a sinle job with active process. If exceeded then set to Failed.*/
|
||||
'jobRerunAttemptNumber' => 1, /** Number of attempts to re-run failed jobs. */
|
||||
'cronMinInterval' => 4, /** Min interval (in seconds) between two cron runs. */
|
||||
'crud' => array(
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
"link": "scheduledJob",
|
||||
"field": "job"
|
||||
},
|
||||
"pid": {
|
||||
"type": "int"
|
||||
},
|
||||
"attempts": {
|
||||
"type": "int"
|
||||
},
|
||||
@@ -79,6 +82,9 @@
|
||||
},
|
||||
"status": {
|
||||
"columns": ["status", "deleted"]
|
||||
}
|
||||
},
|
||||
"pid": {
|
||||
"columns": ["status", "pid"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user