jobs refactoring
This commit is contained in:
@@ -31,24 +31,25 @@ namespace Espo\Core\ApplicationRunners;
|
||||
|
||||
use Espo\Core\{
|
||||
Application\Runner,
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
Utils\Config,
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs cron.
|
||||
* Runs Cron.
|
||||
*/
|
||||
class Cron implements Runner
|
||||
{
|
||||
use Cli;
|
||||
use SetupSystemUser;
|
||||
|
||||
protected $cronManager;
|
||||
protected $config;
|
||||
private $jobManager;
|
||||
|
||||
public function __construct(CronManager $cronManager, Config $config)
|
||||
private $config;
|
||||
|
||||
public function __construct(JobManager $jobManager, Config $config)
|
||||
{
|
||||
$this->cronManager = $cronManager;
|
||||
$this->jobManager = $jobManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
@@ -60,6 +61,6 @@ class Cron implements Runner
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cronManager->run();
|
||||
$this->jobManager->process();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Espo\Core\ApplicationRunners;
|
||||
|
||||
use Espo\Core\{
|
||||
Application\Runner,
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
};
|
||||
|
||||
use StdClass;
|
||||
@@ -46,17 +46,17 @@ class Job implements Runner
|
||||
|
||||
protected $params;
|
||||
|
||||
protected $cronManager;
|
||||
private $jobManager;
|
||||
|
||||
public function __construct(CronManager $cronManager, StdClass $params)
|
||||
public function __construct(JobManager $jobManager, StdClass $params)
|
||||
{
|
||||
$this->cronManager = $cronManager;
|
||||
$this->jobManager = $jobManager;
|
||||
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
public function run() : void
|
||||
{
|
||||
$this->cronManager->runJobById($this->params->id);
|
||||
$this->jobManager->runJobById($this->params->id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,21 +32,23 @@ namespace Espo\Core\Console\Commands;
|
||||
use Espo\Core\{
|
||||
ORM\EntityManager,
|
||||
Utils\Util,
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
Console\Command,
|
||||
Console\Params,
|
||||
Console\IO,
|
||||
};
|
||||
|
||||
use Throwable;
|
||||
|
||||
class RunJob implements Command
|
||||
{
|
||||
private $cronManager;
|
||||
private $jobManager;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(CronManager $cronManager, EntityManager $entityManager)
|
||||
public function __construct(JobManager $jobManager, EntityManager $entityManager)
|
||||
{
|
||||
$this->cronManager = $cronManager;
|
||||
$this->jobManager = $jobManager;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
@@ -80,9 +82,10 @@ class RunJob implements Command
|
||||
'targetId' => $targetId,
|
||||
]);
|
||||
|
||||
$result = $this->cronManager->runJob($job);
|
||||
|
||||
if (!$result) {
|
||||
try {
|
||||
$this->jobManager->runJob($job);
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$io->writeLine("Error: Job '{$jobName}' failed to execute.");
|
||||
|
||||
return;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core;
|
||||
namespace Espo\Core\Job;
|
||||
|
||||
use Espo\Core\{
|
||||
Exceptions\Error,
|
||||
@@ -42,6 +42,7 @@ use Espo\Core\{
|
||||
ORM\EntityManager,
|
||||
Utils\Cron\JobTask,
|
||||
Jobs\JobTargeted,
|
||||
Utils\Log,
|
||||
};
|
||||
|
||||
use Espo\Entities\Job as JobEntity;
|
||||
@@ -53,7 +54,7 @@ use Cron\CronExpression;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class CronManager
|
||||
class JobManager
|
||||
{
|
||||
private $cronJobUtil;
|
||||
|
||||
@@ -82,17 +83,19 @@ class CronManager
|
||||
|
||||
protected $lastRunTimeFile = 'data/cache/application/cronLastRunTime.php';
|
||||
|
||||
protected $config;
|
||||
private $config;
|
||||
|
||||
protected $fileManager;
|
||||
private $fileManager;
|
||||
|
||||
protected $entityManager;
|
||||
private $entityManager;
|
||||
|
||||
protected $serviceFactory;
|
||||
private $serviceFactory;
|
||||
|
||||
protected $injectableFactory;
|
||||
private $injectableFactory;
|
||||
|
||||
protected $scheduledJob;
|
||||
private $scheduledJobUtil;
|
||||
|
||||
private $log;
|
||||
|
||||
public function __construct(
|
||||
Config $config,
|
||||
@@ -100,14 +103,16 @@ class CronManager
|
||||
EntityManager $entityManager,
|
||||
ServiceFactory $serviceFactory,
|
||||
InjectableFactory $injectableFactory,
|
||||
ScheduledJob $scheduledJob
|
||||
ScheduledJob $scheduledJobUtil,
|
||||
Log $log
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->fileManager = $fileManager;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->serviceFactory = $serviceFactory;
|
||||
$this->injectableFactory = $injectableFactory;
|
||||
$this->scheduledJob = $scheduledJob;
|
||||
$this->scheduledJobUtil = $scheduledJobUtil;
|
||||
$this->log = $log;
|
||||
|
||||
$this->cronJobUtil = new CronJob($this->config, $this->entityManager);
|
||||
|
||||
@@ -118,26 +123,11 @@ class CronManager
|
||||
$this->useProcessPool = true;
|
||||
}
|
||||
else {
|
||||
$GLOBALS['log']->warning("CronManager: useProcessPool requires pcntl and posix extensions.");
|
||||
$this->log->warning("JobManager: useProcessPool requires pcntl and posix extensions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getScheduledJobUtil()
|
||||
{
|
||||
return $this->scheduledJob;
|
||||
}
|
||||
|
||||
protected function getCronJobUtil()
|
||||
{
|
||||
return $this->cronJobUtil;
|
||||
}
|
||||
|
||||
protected function getCronScheduledJobUtil()
|
||||
{
|
||||
return $this->cronScheduledJobUtil;
|
||||
}
|
||||
|
||||
protected function getLastRunTime()
|
||||
{
|
||||
$lastRunData = $this->fileManager->getPhpContents($this->lastRunTimeFile);
|
||||
@@ -165,6 +155,7 @@ class CronManager
|
||||
{
|
||||
$currentTime = time();
|
||||
$lastRunTime = $this->getLastRunTime();
|
||||
|
||||
$cronMinInterval = $this->config->get('cronMinInterval', 0);
|
||||
|
||||
if ($currentTime > ($lastRunTime + $cronMinInterval)) {
|
||||
@@ -174,47 +165,60 @@ class CronManager
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function useProcessPool()
|
||||
protected function useProcessPool() : bool
|
||||
{
|
||||
return $this->useProcessPool;
|
||||
}
|
||||
|
||||
public function setUseProcessPool(bool $useProcessPool)
|
||||
public function setUseProcessPool(bool $useProcessPool) : void
|
||||
{
|
||||
$this->useProcessPool = $useProcessPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run cron.
|
||||
* Process jobs. Jobs will be created according scheduling. Then pending jobs will be processed.
|
||||
* This method supposed to be called on every Cron run or loop iteration of the Daemon.
|
||||
*/
|
||||
public function run()
|
||||
public function process() : void
|
||||
{
|
||||
if (!$this->checkLastRunTime()) {
|
||||
$GLOBALS['log']->info('CronManager: Stop cron running, too frequent execution.');
|
||||
$this->log->info('JobManager: Skip job processing. Too frequent execution.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setLastRunTime(time());
|
||||
|
||||
$this->getCronJobUtil()->markJobsFailed();
|
||||
$this->getCronJobUtil()->updateFailedJobAttempts();
|
||||
$this->cronJobUtil->markJobsFailed();
|
||||
$this->cronJobUtil->updateFailedJobAttempts();
|
||||
|
||||
$this->createJobsFromScheduledJobs();
|
||||
$this->getCronJobUtil()->removePendingJobDuplicates();
|
||||
|
||||
$this->cronJobUtil->removePendingJobDuplicates();
|
||||
|
||||
$this->processPendingJobs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a portion of pending jobs.
|
||||
* Process pending jobs from a specific queue. Jobs within a queue are processed one by one.
|
||||
*/
|
||||
public function processPendingJobs($queue = null, $limit = null, bool $poolDisabled = false, bool $noLock = false)
|
||||
public function processQueue(string $queue, int $limit) : void
|
||||
{
|
||||
$this->processPendingJobs($queue, $limit, true, true);
|
||||
}
|
||||
|
||||
protected function processPendingJobs(
|
||||
?string $queue = null,
|
||||
?int $limit = null,
|
||||
bool $poolDisabled = false,
|
||||
bool $noLock = false
|
||||
) : void {
|
||||
|
||||
if (is_null($limit)) {
|
||||
$limit = intval($this->config->get('jobMaxPortion', 0));
|
||||
}
|
||||
|
||||
$pendingJobList = $this->getCronJobUtil()->getPendingJobList($queue, $limit);
|
||||
$pendingJobList = $this->cronJobUtil->getPendingJobList($queue, $limit);
|
||||
|
||||
$useProcessPool = $this->useProcessPool();
|
||||
|
||||
@@ -240,7 +244,7 @@ class CronManager
|
||||
}
|
||||
}
|
||||
|
||||
protected function processPendingJob(JobEntity $job, $pool = null, bool $noLock = false)
|
||||
protected function processPendingJob(JobEntity $job, $pool = null, bool $noLock = false) : void
|
||||
{
|
||||
$useProcessPool = (bool) $pool;
|
||||
|
||||
@@ -257,9 +261,9 @@ class CronManager
|
||||
}
|
||||
}
|
||||
|
||||
if ($noLock || $this->getCronJobUtil()->isJobPending($job->id)) {
|
||||
if ($noLock || $this->cronJobUtil->isJobPending($job->id)) {
|
||||
if ($job->get('scheduledJobId')) {
|
||||
if ($this->getCronJobUtil()->isScheduledJobRunning(
|
||||
if ($this->cronJobUtil->isScheduledJobRunning(
|
||||
$job->get('scheduledJobId'), $job->get('targetId'), $job->get('targetType'))
|
||||
) {
|
||||
$skip = true;
|
||||
@@ -309,7 +313,7 @@ class CronManager
|
||||
return;
|
||||
}
|
||||
|
||||
$this->runJob($job);
|
||||
$this->runJobInternal($job);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,13 +344,20 @@ class CronManager
|
||||
|
||||
$this->entityManager->saveEntity($job);
|
||||
|
||||
$this->runJob($job);
|
||||
$this->runJobInternal($job);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a specific job.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function runJob(JobEntity $job)
|
||||
public function runJob(JobEntity $job) : void
|
||||
{
|
||||
$this->runJobInternal($job, true);
|
||||
}
|
||||
|
||||
protected function runJobInternal(JobEntity $job, bool $throwException = false) : void
|
||||
{
|
||||
$isSuccess = true;
|
||||
|
||||
@@ -362,7 +373,8 @@ class CronManager
|
||||
else {
|
||||
$this->runService($job);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$isSuccess = false;
|
||||
|
||||
if ($e->getCode() === -1) {
|
||||
@@ -371,11 +383,15 @@ class CronManager
|
||||
$skipLog = true;
|
||||
}
|
||||
else {
|
||||
$GLOBALS['log']->error(
|
||||
'CronManager: Failed job running, job ['. $job->id .']. Error Details: '.
|
||||
$e->getMessage() .' at '. $e->getFile() . ':' . $e->getLine()
|
||||
$this->log->error(
|
||||
"JobManager: Failed job running, job '{$job->id}'. " .
|
||||
$e->getMessage() . "; at " . $e->getFile() . ":" . $e->getLine() . "."
|
||||
);
|
||||
}
|
||||
|
||||
if ($throwException) {
|
||||
throw new $e;
|
||||
}
|
||||
}
|
||||
|
||||
$status = $isSuccess ? self::SUCCESS : self::FAILED;
|
||||
@@ -389,16 +405,10 @@ class CronManager
|
||||
$this->entityManager->saveEntity($job);
|
||||
|
||||
if ($job->get('scheduledJobId') && !$skipLog) {
|
||||
$this->getCronScheduledJobUtil()->addLogRecord(
|
||||
$this->cronScheduledJobUtil->addLogRecord(
|
||||
$job->get('scheduledJobId'), $status, null, $job->get('targetId'), $job->get('targetType')
|
||||
);
|
||||
}
|
||||
|
||||
if ($isSuccess) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function runScheduledJob(JobEntity $job) : void
|
||||
@@ -411,7 +421,7 @@ class CronManager
|
||||
);
|
||||
}
|
||||
|
||||
$className = $this->getScheduledJobUtil()->getJobClassName($jobName);
|
||||
$className = $this->scheduledJobUtil->getJobClassName($jobName);
|
||||
|
||||
if (!$className) {
|
||||
throw new Error("No class name for job {$jobName}.");
|
||||
@@ -434,7 +444,7 @@ class CronManager
|
||||
$obj->run();
|
||||
}
|
||||
|
||||
protected function runService(JobEntity $job)
|
||||
protected function runService(JobEntity $job) : void
|
||||
{
|
||||
$serviceName = $job->get('serviceName');
|
||||
|
||||
@@ -467,7 +477,7 @@ class CronManager
|
||||
{
|
||||
$jobName = $job->get('job');
|
||||
|
||||
$className = $this->getScheduledJobUtil()->getJobClassName($jobName);
|
||||
$className = $this->scheduledJobUtil->getJobClassName($jobName);
|
||||
|
||||
if (!$className) {
|
||||
throw new Error("No class name for job {$jobName}.");
|
||||
@@ -490,10 +500,10 @@ class CronManager
|
||||
$obj->run();
|
||||
}
|
||||
|
||||
protected function createJobsFromScheduledJobs()
|
||||
protected function createJobsFromScheduledJobs() : void
|
||||
{
|
||||
$activeScheduledJobList = $this->getCronScheduledJobUtil()->getActiveScheduledJobList();
|
||||
$runningScheduledJobIdList = $this->getCronJobUtil()->getRunningScheduledJobIdList();
|
||||
$activeScheduledJobList = $this->cronScheduledJobUtil->getActiveScheduledJobList();
|
||||
$runningScheduledJobIdList = $this->cronJobUtil->getRunningScheduledJobIdList();
|
||||
|
||||
foreach ($activeScheduledJobList as $scheduledJob) {
|
||||
$scheduling = $scheduledJob->get('scheduling');
|
||||
@@ -508,8 +518,8 @@ class CronManager
|
||||
$cronExpression = CronExpression::factory($scheduling);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$GLOBALS['log']->error(
|
||||
'CronManager (ScheduledJob ' . $scheduledJob->id . '): Scheduling string error - ' .
|
||||
$this->log->error(
|
||||
'JobManager (ScheduledJob ' . $scheduledJob->id . '): Scheduling string error - ' .
|
||||
$e->getMessage() . '.'
|
||||
);
|
||||
|
||||
@@ -520,22 +530,22 @@ class CronManager
|
||||
$nextDate = $cronExpression->getNextRunDate()->format('Y-m-d H:i:s');
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$GLOBALS['log']->error(
|
||||
'CronManager (ScheduledJob '. $scheduledJob->id . '): ' .
|
||||
$this->log->error(
|
||||
'JobManager (ScheduledJob '. $scheduledJob->id . '): ' .
|
||||
'Unsupported CRON expression ' . $scheduling . '.'
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$jobAlreadyExists = $this->getCronJobUtil()->hasScheduledJobOnMinute($scheduledJob->id, $nextDate);
|
||||
$jobAlreadyExists = $this->cronJobUtil->hasScheduledJobOnMinute($scheduledJob->id, $nextDate);
|
||||
|
||||
if ($jobAlreadyExists) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$className = $this->getScheduledJobUtil()->getJobClassName($scheduledJob->get('job'));
|
||||
$className = $this->scheduledJobUtil->getJobClassName($scheduledJob->get('job'));
|
||||
|
||||
if ($className) {
|
||||
if (method_exists($className, 'prepare')) {
|
||||
@@ -551,7 +561,7 @@ class CronManager
|
||||
continue;
|
||||
}
|
||||
|
||||
$pendingCount = $this->getCronJobUtil()->getPendingCountByScheduledJobId($scheduledJob->id);
|
||||
$pendingCount = $this->cronJobUtil->getPendingCountByScheduledJobId($scheduledJob->id);
|
||||
|
||||
if ($asSoonAsPossible) {
|
||||
if ($pendingCount > 0) {
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace Espo\Core\Utils\Cron;
|
||||
|
||||
use Espo\Core\{
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
Utils\Config,
|
||||
ORM\EntityManager,
|
||||
Utils\System,
|
||||
@@ -73,7 +73,7 @@ class Job
|
||||
return false;
|
||||
}
|
||||
|
||||
return $job->get('status') === CronManager::PENDING;
|
||||
return $job->get('status') === JobManager::PENDING;
|
||||
}
|
||||
|
||||
public function getPendingJobList($queue = null, $limit = 0)
|
||||
@@ -92,7 +92,7 @@ class Job
|
||||
'data',
|
||||
],
|
||||
'whereClause' => [
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
'executeTime<=' => date('Y-m-d H:i:s'),
|
||||
'queue' => $queue,
|
||||
],
|
||||
@@ -113,7 +113,7 @@ class Job
|
||||
|
||||
$where = [
|
||||
'scheduledJobId' => $scheduledJobId,
|
||||
'status' => [CronManager::RUNNING, CronManager::READY],
|
||||
'status' => [JobManager::RUNNING, JobManager::READY],
|
||||
];
|
||||
|
||||
if ($targetId && $targetType) {
|
||||
@@ -173,7 +173,7 @@ class Job
|
||||
->getRepository('Job')
|
||||
->where([
|
||||
'scheduledJobId' => $scheduledJobId,
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
])
|
||||
->count();
|
||||
|
||||
@@ -209,7 +209,7 @@ class Job
|
||||
'startedAt'
|
||||
])
|
||||
->where([
|
||||
'status' => CronManager::RUNNING,
|
||||
'status' => JobManager::RUNNING,
|
||||
'startedAt<' => $dateTimeThreshold,
|
||||
])
|
||||
->find();
|
||||
@@ -244,7 +244,7 @@ class Job
|
||||
'startedAt',
|
||||
])
|
||||
->where([
|
||||
'status' => CronManager::READY,
|
||||
'status' => JobManager::READY,
|
||||
'startedAt<' => $dateTimeThreshold,
|
||||
])
|
||||
->find();
|
||||
@@ -276,7 +276,7 @@ class Job
|
||||
'startedAt'
|
||||
])
|
||||
->where([
|
||||
'status' => CronManager::RUNNING,
|
||||
'status' => JobManager::RUNNING,
|
||||
'executeTime<' => $dateTimeThreshold,
|
||||
])
|
||||
->find();
|
||||
@@ -310,7 +310,7 @@ class Job
|
||||
->update()
|
||||
->in('Job')
|
||||
->set([
|
||||
'status' => CronManager::FAILED,
|
||||
'status' => JobManager::FAILED,
|
||||
'attempts' => 0,
|
||||
])
|
||||
->where([
|
||||
@@ -327,7 +327,7 @@ class Job
|
||||
|
||||
$this->cronScheduledJob->addLogRecord(
|
||||
$job->get('scheduledJobId'),
|
||||
CronManager::FAILED,
|
||||
JobManager::FAILED,
|
||||
$job->get('startedAt'),
|
||||
$job->get('targetId'),
|
||||
$job->get('targetType')
|
||||
@@ -345,7 +345,7 @@ class Job
|
||||
->select(['scheduledJobId'])
|
||||
->where([
|
||||
'scheduledJobId!=' => null,
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
'executeTime<=' => date('Y-m-d H:i:s'),
|
||||
'targetId' => null,
|
||||
])
|
||||
@@ -372,7 +372,7 @@ class Job
|
||||
->select(['id'])
|
||||
->where([
|
||||
'scheduledJobId' => $scheduledJobId,
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
])
|
||||
->order('executeTime')
|
||||
->limit(0, 1000)
|
||||
@@ -408,7 +408,7 @@ class Job
|
||||
$jobList = $this->entityManager->getRepository('Job')
|
||||
->select(['id', 'attempts', 'failedAttempts'])
|
||||
->where([
|
||||
'status' => CronManager::FAILED,
|
||||
'status' => JobManager::FAILED,
|
||||
'executeTime<=' => date('Y-m-d H:i:s'),
|
||||
'attempts>' => 0,
|
||||
])
|
||||
@@ -422,7 +422,7 @@ class Job
|
||||
$failedAttempts = $failedAttempts + 1;
|
||||
|
||||
$job->set([
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
'attempts' => $attempts,
|
||||
'failedAttempts' => $failedAttempts,
|
||||
]);
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Espo\Jobs;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
|
||||
use Espo\Core\{
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
ServiceFactory,
|
||||
ORM\EntityManager,
|
||||
Jobs\JobTargeted,
|
||||
@@ -97,7 +97,7 @@ class CheckEmailAccounts implements JobTargeted
|
||||
->getRepository('Job')
|
||||
->where([
|
||||
'scheduledJobId' => $scheduledJob->id,
|
||||
'status' => [CronManager::RUNNING, CronManager::READY],
|
||||
'status' => [JobManager::RUNNING, JobManager::READY],
|
||||
'targetType' => 'EmailAccount',
|
||||
'targetId' => $entity->id,
|
||||
])
|
||||
@@ -111,7 +111,7 @@ class CheckEmailAccounts implements JobTargeted
|
||||
->getRepository('Job')
|
||||
->where([
|
||||
'scheduledJobId' => $scheduledJob->id,
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
'targetType' => 'EmailAccount',
|
||||
'targetId' => $entity->id,
|
||||
])
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Espo\Jobs;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
|
||||
use Espo\Core\{
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
ServiceFactory,
|
||||
ORM\EntityManager,
|
||||
Jobs\JobTargeted,
|
||||
@@ -95,7 +95,7 @@ class CheckInboundEmails implements JobTargeted
|
||||
->getRepository('Job')
|
||||
->where([
|
||||
'scheduledJobId' => $scheduledJob->id,
|
||||
'status' => [CronManager::RUNNING, CronManager::READY],
|
||||
'status' => [JobManager::RUNNING, JobManager::READY],
|
||||
'targetType' => 'InboundEmail',
|
||||
'targetId' => $entity->id,
|
||||
])
|
||||
@@ -109,7 +109,7 @@ class CheckInboundEmails implements JobTargeted
|
||||
->getRepository('Job')
|
||||
->where([
|
||||
'scheduledJobId' => $scheduledJob->id,
|
||||
'status' => CronManager::PENDING,
|
||||
'status' => JobManager::PENDING,
|
||||
'targetType' => 'InboundEmail',
|
||||
'targetId' => $entity->id,
|
||||
])
|
||||
|
||||
@@ -30,19 +30,20 @@
|
||||
namespace Espo\Jobs;
|
||||
|
||||
use Espo\Core\{
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
Utils\Config,
|
||||
Jobs\Job,
|
||||
};
|
||||
|
||||
class ProcessJobQueueE0 implements Job
|
||||
{
|
||||
protected $cronManager;
|
||||
protected $config;
|
||||
private $jobManager;
|
||||
|
||||
public function __construct(CronManager $cronManager, Config $config)
|
||||
private $config;
|
||||
|
||||
public function __construct(JobManager $jobManager, Config $config)
|
||||
{
|
||||
$this->cronManager = $cronManager;
|
||||
$this->jobManager = $jobManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
@@ -50,6 +51,6 @@ class ProcessJobQueueE0 implements Job
|
||||
{
|
||||
$limit = $this->config->get('jobE0MaxPortion', 100);
|
||||
|
||||
$this->cronManager->processPendingJobs('e0', $limit, true, true);
|
||||
$this->jobManager->processQueue('e0', $limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,19 +30,20 @@
|
||||
namespace Espo\Jobs;
|
||||
|
||||
use Espo\Core\{
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
Utils\Config,
|
||||
Jobs\Job,
|
||||
};
|
||||
|
||||
class ProcessJobQueueQ0 implements Job
|
||||
{
|
||||
protected $cronManager;
|
||||
protected $config;
|
||||
private $jobManager;
|
||||
|
||||
public function __construct(CronManager $cronManager, Config $config)
|
||||
private $config;
|
||||
|
||||
public function __construct(JobManager $jobManager, Config $config)
|
||||
{
|
||||
$this->cronManager = $cronManager;
|
||||
$this->jobManager = $jobManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
@@ -50,6 +51,6 @@ class ProcessJobQueueQ0 implements Job
|
||||
{
|
||||
$limit = $this->config->get('jobQ0MaxPortion', 200);
|
||||
|
||||
$this->cronManager->processPendingJobs('q0', $limit, true, true);
|
||||
$this->jobManager->processQueue('q0', $limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,19 +30,20 @@
|
||||
namespace Espo\Jobs;
|
||||
|
||||
use Espo\Core\{
|
||||
CronManager,
|
||||
Job\JobManager,
|
||||
Utils\Config,
|
||||
Jobs\Job,
|
||||
};
|
||||
|
||||
class ProcessJobQueueQ1 implements Job
|
||||
{
|
||||
protected $cronManager;
|
||||
protected $config;
|
||||
private $jobManager;
|
||||
|
||||
public function __construct(CronManager $cronManager, Config $config)
|
||||
private $config;
|
||||
|
||||
public function __construct(JobManager $jobManager, Config $config)
|
||||
{
|
||||
$this->cronManager = $cronManager;
|
||||
$this->jobManager = $jobManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
@@ -50,6 +51,6 @@ class ProcessJobQueueQ1 implements Job
|
||||
{
|
||||
$limit = $this->config->get('jobQ1MaxPortion', 500);
|
||||
|
||||
$this->cronManager->processPendingJobs('q1', $limit, true, true);
|
||||
$this->jobManager->processQueue('q1', $limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Espo\Repositories;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\CronManager;
|
||||
use Espo\Core\Job\JobManager;
|
||||
|
||||
class ScheduledJob extends \Espo\Core\Repositories\Database
|
||||
{
|
||||
@@ -46,10 +46,13 @@ class ScheduledJob extends \Espo\Core\Repositories\Database
|
||||
parent::afterSave($entity, $options);
|
||||
|
||||
if ($entity->isAttributeChanged('scheduling')) {
|
||||
$jobList = $this->getEntityManager()->getRepository('Job')->where([
|
||||
'scheduledJobId' => $entity->id,
|
||||
'status' => CronManager::PENDING,
|
||||
])->find();
|
||||
$jobList = $this->getEntityManager()
|
||||
->getRepository('Job')
|
||||
->where([
|
||||
'scheduledJobId' => $entity->id,
|
||||
'status' => JobManager::PENDING,
|
||||
])
|
||||
->find();
|
||||
|
||||
foreach ($jobList as $job) {
|
||||
$this->getEntityManager()->removeEntity($job);
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
"fileStorageManager": {
|
||||
"className": "Espo\\Core\\FileStorage\\Manager"
|
||||
},
|
||||
"cronManager": {
|
||||
"className": "Espo\\Core\\CronManager"
|
||||
"jobManager": {
|
||||
"className": "Espo\\Core\\Job\\JobManager"
|
||||
},
|
||||
"webSocketSubmission": {
|
||||
"className": "Espo\\Core\\WebSocket\\Submission"
|
||||
|
||||
+58
-38
@@ -27,93 +27,113 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core;
|
||||
namespace tests\unit\Espo\Core\Job;
|
||||
|
||||
use tests\unit\ReflectionHelper;
|
||||
|
||||
use Espo\Core\CronManager;
|
||||
use Espo\Core\{
|
||||
Job\JobManager,
|
||||
ServiceFactory,
|
||||
Utils\Config,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\ScheduledJob,
|
||||
ORM\EntityManager,
|
||||
InjectableFactory,
|
||||
Utils\Log,
|
||||
};
|
||||
|
||||
class CronManagerTest extends \PHPUnit\Framework\TestCase
|
||||
class JobManagerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $object;
|
||||
|
||||
protected $objects;
|
||||
|
||||
protected $filesPath= 'tests/unit/testData/EntryPoints';
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->objects['serviceFactory'] = $this->getMockBuilder('Espo\\Core\\ServiceFactory')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['config'] = $this->getMockBuilder('Espo\\Core\\Utils\\Config')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['fileManager'] = $this->getMockBuilder('Espo\\Core\\Utils\\File\\Manager')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['scheduledJob'] = $this->getMockBuilder('Espo\\Core\\Utils\\ScheduledJob')->disableOriginalConstructor()->getMock();
|
||||
$this->objects['entityManager'] = $this->getMockBuilder('Espo\\Core\\ORM\\EntityManager')->disableOriginalConstructor()->getMock();
|
||||
$this->serviceFactory = $this->getMockBuilder(ServiceFactory::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->objects['injectableFactory'] = $this->getMockBuilder('Espo\\Core\\InjectableFactory')->disableOriginalConstructor()->getMock();
|
||||
$this->config = $this->getMockBuilder(Config::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->object = new CronManager(
|
||||
$this->objects['config'],
|
||||
$this->objects['fileManager'],
|
||||
$this->objects['entityManager'],
|
||||
$this->objects['serviceFactory'],
|
||||
$this->objects['injectableFactory'],
|
||||
$this->objects['scheduledJob']
|
||||
$this->fileManager = $this->getMockBuilder(FileManager::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->scheduledJob = $this->getMockBuilder(ScheduledJob::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->entityManager = $this->getMockBuilder(EntityManager::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->injectableFactory = $this->getMockBuilder(InjectableFactory::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->log = $this->createMock(Log::class);
|
||||
|
||||
$this->manager = new JobManager(
|
||||
$this->config,
|
||||
$this->fileManager,
|
||||
$this->entityManager,
|
||||
$this->serviceFactory,
|
||||
$this->injectableFactory,
|
||||
$this->scheduledJob,
|
||||
$this->log
|
||||
);
|
||||
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
$this->reflection = new ReflectionHelper($this->manager);
|
||||
}
|
||||
|
||||
protected function tearDown() : void
|
||||
{
|
||||
$this->object = NULL;
|
||||
$this->manager = NULL;
|
||||
}
|
||||
|
||||
function testCheckLastRunTimeFileDoesnotExist()
|
||||
public function testCheckLastRunTimeFileDoesnotExist()
|
||||
{
|
||||
$this->objects['fileManager']
|
||||
$this->fileManager
|
||||
->expects($this->once())
|
||||
->method('getPhpContents')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnValue(50));
|
||||
|
||||
$this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', array()));
|
||||
$this->assertTrue($this->reflection->invokeMethod('checkLastRunTime', []));
|
||||
}
|
||||
|
||||
public function testCheckLastRunTime()
|
||||
{
|
||||
$this->objects['fileManager']
|
||||
$this->fileManager
|
||||
->expects($this->once())
|
||||
->method('getPhpContents')
|
||||
->will($this->returnValue(array(
|
||||
->will(
|
||||
$this->returnValue([
|
||||
'time' => time() - 60,
|
||||
)));
|
||||
])
|
||||
);
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnValue(50));
|
||||
|
||||
$this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', array()));
|
||||
$this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', []));
|
||||
}
|
||||
|
||||
public function testCheckLastRunTimeTooFrequency()
|
||||
{
|
||||
$this->objects['fileManager']
|
||||
$this->fileManager
|
||||
->expects($this->once())
|
||||
->method('getPhpContents')
|
||||
->will($this->returnValue(array(
|
||||
->will(
|
||||
$this->returnValue([
|
||||
'time' => time() - 49,
|
||||
)));
|
||||
])
|
||||
);
|
||||
|
||||
$this->objects['config']
|
||||
$this->config
|
||||
->expects($this->exactly(1))
|
||||
->method('get')
|
||||
->will($this->returnValue(50));
|
||||
|
||||
$this->assertFalse($this->reflection->invokeMethod('checkLastRunTime', array()));
|
||||
$this->assertFalse($this->reflection->invokeMethod('checkLastRunTime', []));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user