| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- <?php
- namespace ModulesGarden\ModuleFramework\Core\CommandLine;
- use ModulesGarden\ModuleFramework\Core\FileReader\Validator;
- use ModulesGarden\ModuleFramework\Core\ModuleConstants;
- use ModulesGarden\ModuleFramework\Core\DependencyInjection;
- use ModulesGarden\ModuleFramework\Core\FileReader\File;
- use ModulesGarden\ModuleFramework\Core\CommandLine\ReaderCronTask;
- use ModulesGarden\ModuleFramework\Core\Models\CronTabs;
- /**
- * Description of CronManager
- *
- * @author Rafał
- */
- class CronManager {
-
- const AVAILABLE_MODES = ['cli', 'cgi-fcgi'];
-
- protected $arguments = [];
-
- protected $appCronPath = '';
-
- protected $coreCronPath = '';
-
- protected $parentUId;
-
- protected $parentGId;
-
- protected $cronPids = '';
-
- protected $isParent = true;
-
- protected $parentId;
-
- protected $childId;
- /**
- * @var Validator
- */
- protected $fileValidator;
-
- public function __construct(Validator $fileValidator) {
- $this->fileValidator = $fileValidator;
- $this->appCronPath = ModuleConstants::getModuleRootDir() . DS . 'app' . DS . 'Cron' . DS;
- $this->coreCronPath = ModuleConstants::getModuleRootDir() . DS . 'core' . DS . 'Cron' . DS;
- $this->cronPidsPath = ModuleConstants::getModuleRootDir() . DS . 'storage' . DS . 'crons' . DS;
-
- if($this->fileValidator->isExist($this->cronPidsPath) === false)
- {
- mkdir($this->cronPidsPath);
- File::setPermission($this->cronPidsPath);
- }
- if (self::isThread())
- {
- $this->appCronPath .= "Thread" . DS;
- $this->coreCronPath .= "Thread" . DS;
- }
- else
- {
- $this->appCronPath .= "WithoutThread" . DS;
- $this->coreCronPath .= "WithoutThread" . DS;
- }
-
- $this->parentGId = getmygid();
- $this->parentUId = getmyuid();
- }
-
- public function setArgv($arguments)
- {
- $this->arguments = $arguments;
-
- return $this;
- }
-
- public function execute()
- {
- $this->loadArguments();
-
- if($this->isInCliMode() === false)
- {
- return $this;
- }
- if (count($this->arguments) == 0)
- {
- $this->arguments = ReaderCronTask::get();
- }
-
- $this->loadDefaultCronManager();
- foreach ($this->arguments as $className)
- {
- $className = trim(trim($className, '--'), '-');
- $class = ModuleConstants::getRootNamespace() . "\\";
- if ($this->fileValidator->isExist($this->appCronPath . $className . ".php"))
- {
- $class .= "App\Cron\\" . $this->getType() . "\\" . $className;
- $this->runTask($class, $className);
- }
- elseif ($this->fileValidator->isExist($this->coreCronPath . $className . ".php"))
- {
- $class .= "Core\Cron\\" . $this->getType() . "\\" . $className;
- $this->runTask($class, $className);
- }
- }
-
- return $this;
- }
-
- protected function runTask($class, $className)
- {
- if ($this->classExist($class) === true && $this->isCronRunning($className) === false)
- {
- if ($this->beforeRunTask($className) === false)
- {
- return;
- }
-
- $instant = DependencyInjection::create($class, null, (class_exists(\Thread::class)?false:true));
- $instant->setCronManager($this);
- $instant->setClassName($className);
- if (self::isThread() === false)
- {
- $instant->ischild(!$this->isParent)
- ->setChildId($this->childId)
- ->setParentId($this->parentId)
- ->setParentGroupId($this->parentGId)
- ->setParentUserId($this->parentUId);
- }
- $instant->start();
- unset($instant);
- $this->afterRunTask($className);
- }
- }
-
- protected function getType()
- {
- return (self::isThread()?'Thread':'WithoutThread');
- }
-
- public static function isThread()
- {
- return class_exists(\Thread::class);
- }
-
- protected function loadArguments()
- {
- $deleteClass = [];
- foreach ($this->arguments as $key => $name) {
- if (strpos($name, 'cron.php') !== false)
- {
- $deleteClass[] = $key;
- }
- elseif ($name === '--parent')
- {
- $this->parentId = $this->arguments[$key + 1];
- $this->isParent = false;
- $deleteClass[] = $key;
- $deleteClass[] = $key + 1;
- }
- elseif ($name === '--child')
- {
- $this->childId = $this->arguments[$key + 1];
- $this->isParent = false;
- $deleteClass[] = $key;
- $deleteClass[] = $key + 1;
- }
- elseif ($name === '--parentuid')
- {
- $this->parentUId = $this->arguments[$key + 1];
- $deleteClass[] = $key;
- $deleteClass[] = $key + 1;
- }
- elseif ($name === '--parentgid')
- {
- $this->parentGId = $this->arguments[$key + 1];
- $deleteClass[] = $key;
- $deleteClass[] = $key + 1;
- }
- }
-
- foreach ($deleteClass as $clasKey)
- {
- unset($this->arguments[$clasKey]);
- }
-
- return $this;
- }
-
- protected function classExist($name)
- {
- return class_exists($name);
- }
-
- public static function updatePids($name, $id = '')
- {
- touch(ModuleConstants::getModuleRootDir() . DS . 'storage' . DS . 'crons' . DS . $name. 'Pid' . $id . '.php');
- }
-
- public static function removePids($name, $id = '')
- {
- unlink(ModuleConstants::getModuleRootDir() . DS . 'storage' . DS . 'crons' . DS . $name. 'Pid' . $id . '.php');
- }
-
- public static function existPids($name, $id = '')
- {
- return file_exists(ModuleConstants::getModuleRootDir() . DS . 'storage' . DS . 'crons' . DS . $name. 'Pid' . $id . '.php');
- }
- public function createPids($file)
- {
- return file_put_contents($file, '<?php die(); '.getmypid());
- }
-
- public function isChildRunning($name, $id)
- {
- $file = $this->cronPidsPath . $name. 'Pid' . $id . '.php';
-
- if($this->fileValidator->isExist($file) && filemtime($file) > time() - 7200)
- {
- return true;
- }
- return false;
- }
-
- private function isCronRunning($name)
- {
- if ($this->isParent === false)
- {
- $file = $this->cronPidsPath . $name. 'Pid' . $this->childId . '.php';
-
- if($this->fileValidator->isExist($file) && filemtime($file) > time() - 7200)
- {
- return true;
- }
- if($this->createPids($file) === false)
- {
- return true;
- }
- }
-
- return false;
-
- /**
- if(PHP_OS == "Linux")
- {
- $out = null;
- exec("ps aux | grep 'php -q.*modules/addons/AdvancedBilling/cron/cron.php$' | grep -v 'grep'", $out);
- if(count($out) > 1)
- {
- return true;
- }
- }
- **/
- }
-
- private function isInCliMode()
- {
- if (in_array(php_sapi_name(), self::AVAILABLE_MODES))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
-
- protected function loadDefaultCronManager()
- {
- $defaultCron = CronTabs::ifDefaultCronManager()->first();
- if ($this->isParent && $defaultCron && $defaultCron->status != 'start')
- {
- CronTabs::ifDefaultCronManager()->updateStatus('start');
- unset($defaultCron);
- }
- elseif ($this->isParent && !$defaultCron)
- {
- CronTabs::create([
- 'name' => CronTabs::DEFAULT_CRON_MANAGER_NAME,
- 'status' => 'start',
- 'params' => [],
- 'errors' => []
- ]);
- }
-
- return $this;
- }
-
- protected function beforeRunTask($className)
- {
- if ($this->isParent)
- {
- if (CronTabs::ifDefaultCronManager()->getQuery()->first()->status == 'stop')
- {
- exit;
- }
- $cronTask = CronTabs::ifName($className)->getQuery()->first();
- if ($cronTask && $cronTask->status != 'stop')
- {
- return false;
- }
- $params = [
- 'parentId' => getmypid(),
- 'parentUId' => $this->parentUId,
- 'parentGId' => $this->parentGId
- ];
- if ($cronTask)
- {
- CronTabs::ifName($className)->updateStatus('start', $params);
- }
- else
- {
- CronTabs::create([
- 'name' => $className,
- 'status' => 'start',
- 'params' => $params,
- 'errors' => []
- ]);
- }
- usleep(500000);
- $cronTask = (new CronTabs())->ifName($className)->getQuery()->first();
- if ($this->isParent && json_decode($cronTask->params)->parentId != getmypid())
- {
- return false;
- }
- }
-
- return true;
- }
-
- protected function afterRunTask($className)
- {
- if ($this->isParent)
- {
- CronTabs::ifName($className)->updateStatus();
- }
-
- return $this;
- }
- }
|