classes/XLite/Core/Task/ATask.php line 70

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
  4.  * See https://www.x-cart.com/license-agreement.html for license details.
  5.  */
  6. namespace XLite\Core\Task;
  7. use Symfony\Component\Console\Output\OutputInterface;
  8. use XCart\Event\Task\CronEvent;
  9. /**
  10.  * Abstract task
  11.  */
  12. abstract class ATask extends \XLite\Base
  13. {
  14.     /**
  15.      * Model
  16.      *
  17.      * @var \XLite\Model\Task
  18.      */
  19.     protected $model;
  20.     /**
  21.      * Start time
  22.      *
  23.      * @var integer
  24.      */
  25.     protected $startTime;
  26.     /**
  27.      * Last step flag
  28.      *
  29.      * @var boolean
  30.      */
  31.     protected $lastStep false;
  32.     /**
  33.      * Result operation message
  34.      *
  35.      * @var string
  36.      */
  37.     protected $message;
  38.     /**
  39.      * @var OutputInterface
  40.      */
  41.     protected $output;
  42.     /**
  43.      * Get title
  44.      *
  45.      * @return string
  46.      */
  47.     abstract public function getTitle();
  48.     /**
  49.      * Run step
  50.      */
  51.     abstract protected function runStep();
  52.     /**
  53.      * Constructor
  54.      */
  55.     public function __construct()
  56.     {
  57.     }
  58.     public function handleTask(CronEvent $event): void
  59.     {
  60.         $this->model \XLite\Core\Database::getRepo('XLite\Model\Task')->findOneBy(['owner' => static::class]);
  61.         $this->startTime $event->getStartTime();
  62.         $this->output $event->getOutput();
  63.         if (!$this->model->isExpired()) {
  64.             return;
  65.         }
  66.         $this->runRunner();
  67.         sleep($event->getSleepTime());
  68.         if (!$this->checkThreadResource($event)) {
  69.             $time gmdate('H:i:s'\XLite\Core\Converter::time() - $this->startTime);
  70.             $memory \XLite\Core\Converter::formatFileSize(memory_get_usage(true));
  71.             $this->printContent('Step is interrupted (time: ' $time '; memory usage: ' $memory ')');
  72.             $event->stopPropagation();
  73.         }
  74.     }
  75.     /**
  76.      * Get message
  77.      *
  78.      * @return string
  79.      */
  80.     public function getMessage()
  81.     {
  82.         return $this->message;
  83.     }
  84.     /**
  85.      * Check - task ready or not
  86.      *
  87.      * @return boolean
  88.      */
  89.     public function isReady()
  90.     {
  91.         return true;
  92.     }
  93.     /**
  94.      * Should task started if previous attempt has failed
  95.      *
  96.      * @return boolean
  97.      */
  98.     public function shouldRunIfCrashed()
  99.     {
  100.         return true;
  101.     }
  102.     /**
  103.      * Lock key
  104.      *
  105.      * @return string
  106.      */
  107.     public function getLockKey()
  108.     {
  109.         return static::class . $this->model->getId();
  110.     }
  111.     /**
  112.      * Check - task ready or not
  113.      *
  114.      * @return boolean
  115.      */
  116.     public function isRunning()
  117.     {
  118.         return \XLite\Core\Lock\FileLock::getInstance()->isRunning(
  119.             $this->getLockKey(),
  120.             !$this->shouldRunIfCrashed()
  121.         );
  122.     }
  123.     /**
  124.      * Mark task as running
  125.      *
  126.      * @return void
  127.      */
  128.     protected function markAsRunning()
  129.     {
  130.         \XLite\Core\Lock\FileLock::getInstance()->setRunning(
  131.             $this->getLockKey()
  132.         );
  133.     }
  134.     /**
  135.      * mark as not running
  136.      *
  137.      * @return void
  138.      */
  139.     protected function release()
  140.     {
  141.         \XLite\Core\Lock\FileLock::getInstance()->release(
  142.             $this->getLockKey()
  143.         );
  144.     }
  145.     /**
  146.      * @return void
  147.      */
  148.     protected function runRunner()
  149.     {
  150.         $silence = !$this->getTitle();
  151.         if ($this->isReady() && !$this->isRunning()) {
  152.             if (!$silence) {
  153.                 $this->printContent($this->getTitle() . ' ... ');
  154.             }
  155.             $this->run();
  156.             if (!$silence) {
  157.                 $this->printContent($this->getMessage() ?: 'done');
  158.             }
  159.         } elseif ($this->isRunning()) {
  160.             $msg = !$this->shouldRunIfCrashed()
  161.                 ? '| Task will not be restarted because previous attempt has failed. Remove lock files manually to start the task'
  162.                 '';
  163.             $this->printContent($this->getTitle() . ' ... Already running ' $msg);
  164.         }
  165.         if (!$silence) {
  166.             $this->printContent(PHP_EOL);
  167.         }
  168.         \XLite\Core\Database::getEM()->flush();
  169.     }
  170.     /**
  171.      * Run task
  172.      */
  173.     public function run()
  174.     {
  175.         if ($this->isValid()) {
  176.             $this->prepareStep();
  177.             $this->markAsRunning();
  178.             $this->runStep();
  179.             if ($this->isLastStep()) {
  180.                 $this->finalizeTask();
  181.             } else {
  182.                 $this->finalizeStep();
  183.             }
  184.         } elseif (!$this->message) {
  185.             $this->message 'invalid';
  186.         }
  187.     }
  188.     /**
  189.      * Check thread resource
  190.      *
  191.      * @return boolean
  192.      */
  193.     protected function checkThreadResource($event)
  194.     {
  195.         return time() - $event->getStartTime() < $event->getTimeLimit()
  196.             && $event->getMemoryLimitIni() - memory_get_usage(true) > $event->getMemoryLimit();
  197.     }
  198.     /**
  199.      * Print content
  200.      *
  201.      * @param string $str Content
  202.      *
  203.      * @return void
  204.      */
  205.     protected function printContent($str)
  206.     {
  207.         if (PHP_SAPI === 'cli') {
  208.             $this->output->write($str);
  209.         }
  210.     }
  211.     /**
  212.      * Prepare step
  213.      *
  214.      * @return void
  215.      */
  216.     protected function prepareStep()
  217.     {
  218.     }
  219.     /**
  220.      * Check - current step is last or not
  221.      *
  222.      * @return boolean
  223.      */
  224.     protected function isLastStep()
  225.     {
  226.         return $this->lastStep;
  227.     }
  228.     /**
  229.      * Finalize task (last step)
  230.      */
  231.     protected function finalizeTask()
  232.     {
  233.         $this->release();
  234.         $this->close();
  235.     }
  236.     /**
  237.      * Finalize step
  238.      */
  239.     protected function finalizeStep()
  240.     {
  241.     }
  242.     /**
  243.      * Check availability
  244.      *
  245.      * @return boolean
  246.      */
  247.     protected function isValid()
  248.     {
  249.         return true;
  250.     }
  251.     /**
  252.      * Close task
  253.      */
  254.     protected function close()
  255.     {
  256.         \XLite\Core\Database::getEM()->remove($this->model);
  257.     }
  258. }