Merge branch 'pid' into hotfix/5.0.4

This commit is contained in:
Taras Machyshyn
2018-01-30 12:52:15 +02:00
5 changed files with 100 additions and 23 deletions
+1
View File
@@ -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');
+57 -22
View File
@@ -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();
}
}
+34
View File
@@ -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"]
}
}
}