Files
pathfinder/app/main/lib/Cron.php
Mark Friedrich 9cb013e9ff - BC Break: Upgraded required _PHP_ v7.1v7.2
- BC Break: Core _PHP_ framework + dependencies moved into `composer.json` and are no longer part of this repo
- Upgraded some 3rd party _Composer_ dependencies: `monolog/monolog`, `swiftmailer/swiftmailer`, `league/html-to-markdown`, `react/socket`, `react/promise-stream`
- Fixed a bug where `/setup` throws HTTP `5xx` error if no `pathfinder` DB exists
- Fixed compatibility issue with PHP `v7.4`, closed #887
2019-12-14 21:34:18 +01:00

161 lines
4.6 KiB
PHP

<?php
namespace lib;
use Model\Pathfinder;
/**
* Class Cron
* @package lib
*
* @property array $jobs
*/
class Cron extends \Cron {
/**
* execution time buffer in percent
* -> cronJobs that exceed avg. exec. time + DEFAULT_BUFFER_EXEC_TIME show warnings
*/
const DEFAULT_BUFFER_EXEC_TIME = 20;
/**
* execution memory buffer in percent
* -> cronJobs that exceed avg. mem. peak + DEFAULT_BUFFER_MEM_PEAK show warnings
*/
const DEFAULT_BUFFER_MEM_PEAK = 20;
/**
* extends parent::isDue()
* -> adds check for "paused" jobs
* @param string $job
* @param int $time
* @return bool
*/
public function isDue($job, $time){
if($isDue = parent::isDue($job, $time)){
// check if job is not paused
if($job = $this->getJob($job)){
if($job->valid() && $job->isPaused){
$isDue = false;
}
}
}
return $isDue;
}
public function execute($job, $async = true) {
return parent::execute($job, $async);
}
/**
* @param $name
* @return string
*/
public function __get($name){
if(in_array($name, ['jobs'])){
return $this->$name;
}else{
return parent::__get($name);
}
}
/**
* @param array $jobConf
* @return array
*/
public function getJobDataFromConf(array $jobConf) : array {
return ['handler' => $jobConf[0], 'expr' => $jobConf[1]];
}
/**
* get all configured cronjobs (read from cron.ini)
* @param array $names
* @return array
*/
public function getJobsConfig(array $names = []) : array {
$config = [];
$jobs = array_filter($this->jobs, function(string $name) use ($names) : bool {
return !empty($names) ? in_array($name, $names) : true;
}, ARRAY_FILTER_USE_KEY );
foreach($jobs as $name => $jobConf){
$jobConf = $this->getJobDataFromConf($jobConf);
if($job = $this->registerJob($name, $jobConf)){
// get job config from DB
$config[$name] = $job->getData();
}else{
// job registration failed (e.g. DB connect failed) -> return min config from cron.ini
$jobConf = (object)$jobConf;
$jobConf->status = ['dbError' => Pathfinder\CronModel::STATUS['dbError']];
$jobConf->history = [];
$config[$name] = $jobConf;
}
$config[$name]->exprPreset = $this->checkPreset($config[$name]->expr);
}
ksort($config);
return $config;
}
/**
* @param string $name
* @param array $jobConf
* @return mixed|void
*/
public function registerJob(string $name, array $jobConf){
// method is called from /setup page -> DB might not be created at this point!
// -> check if DB exists here. Otherwise Cortex()->__construct()
\Base::instance()->DB->setSilent(true);
if(\Base::instance()->DB->getDB(Pathfinder\AbstractPathfinderModel::DB_ALIAS)){
if($job = $this->getJob($name)){
if($job->dry()){
$job->name = $name;
}
$job->setData($jobConf);
return $job->save();
}
}
\Base::instance()->DB->setSilent(false);
}
/**
* find CronModel by job $name
* @param string $name
* @return Pathfinder\CronModel|null
*/
public function getJob(string $name) : ?Pathfinder\CronModel {
$job = null;
try{
/**
* @var $job Pathfinder\CronModel
*/
$jobModel = Pathfinder\AbstractPathfinderModel::getNew('CronModel');
// we need to check if table exists here
// if not we get an error for later insert/update SQL actions
// -> e.g. if job is triggered manually on CLI
if($jobModel->tableExists()){
$jobModel->getByForeignKey('name', $name);
$job = $jobModel;
}
}catch(\Exception $e){
// Cron DB table not exists or other DB issues...
}
return $job;
}
/**
* check expression for a preset
* @param string $expr
* @return bool
*/
protected function checkPreset(string $expr){
if(preg_match('/^@(\w+)$/', $expr,$m)){
if(!isset($this->presets[$m[1]]))
return false;
return $this->presets[$m[1]];
}
return false;
}
}