Example #1
0
 /**
  * Метод выполняет фактическое получение лока
  */
 private function doLock($lockname, $wait)
 {
     PsCheck::notEmptyString($lockname);
     if ($this->lockName == $lockname) {
         $this->lockCnt++;
         $this->LOGGER->info('Lock ident [{}] counter inreased to {}.', $lockname, $this->lockCnt);
         return true;
     }
     check_condition($lockname, 'Lock ident cannot be empty');
     check_condition(!$this->lockName, "Lock [{$lockname}] cannot be set, previous lock [{$this->lockName}] is active");
     $filename = md5($lockname);
     $this->LOGGER->info("Trying to get lock with ident [{$lockname}], mode: {}. Lock file name=[{$filename}].", $wait ? 'WAIT' : 'NOWAIT');
     /**
      * Храним в auto-no-del, а не в autogen, так как можем потерять локи при удалении autogen
      * или вообще не иметь возможности удалить папку autogen.
      */
     $di = DirManager::autoNoDel('locks')->getDirItem(null, $filename, 'lock');
     /*
      * Файл будет создан при открытии
      */
     $fp = fopen($di->getAbsPath(), 'a+');
     do {
         $this->LOGGER->info('Locking file...');
         if (flock($fp, $wait ? LOCK_EX : LOCK_EX | LOCK_NB)) {
             $this->lockCnt = 1;
             $this->lockFile = $fp;
             $this->lockName = $lockname;
             $this->LOGGER->info('Lock acquired!');
             return true;
         }
         //Мы не получили блокировку...
         if ($wait) {
             $this->LOGGER->info('Lock not acquired, sleep for 1 sec');
             sleep(1);
         }
     } while ($wait);
     @fclose($fp);
     $this->LOGGER->info("Lock not setted.\n");
     return false;
 }
Example #2
0
 /**
  * Метод вызывается для выполнения периодических задач cron
  * 
  * @return type
  */
 public function execute()
 {
     if ($this->called) {
         return $this->executed;
         //---
     }
     $this->called = true;
     $LOGGER = PsLogger::inst(__CLASS__);
     $LOGGER->info('Executing {}', __CLASS__);
     /*
      * Получим список классов, которые нужно выполнить
      */
     $processes = ConfigIni::cronProcesses();
     if (empty($processes)) {
         $LOGGER->info('No cron processes configured, fast return...');
         return $this->executed;
         //---
     }
     $processes = array_unique($processes);
     $LOGGER->info('Configured processes: {}', array_to_string($processes));
     foreach ($processes as $class) {
         if (!PsUtil::isInstanceOf($class, 'PsCronProcess')) {
             PsUtil::raise("Class {$class} cannot be executed as cron process, it should be instance of PsCronProcess");
         }
     }
     $locked = PsLock::lock(__CLASS__, false);
     $LOGGER->info('Lock accured ? {}', var_export($locked, true));
     if (!$locked) {
         return $this->executed;
         //---
     }
     $LOCKFILE = DirManager::autoNoDel(DirManager::DIR_SERVICE)->getDirItem(null, __CLASS__, PsConst::EXT_LOCK);
     $LOCKFILE_LIFETIME = $LOCKFILE->getFileLifetime();
     $MAX_LIFETIME = 5 * 60;
     $NED_PROCESS = $LOCKFILE_LIFETIME === null || $LOCKFILE_LIFETIME > $MAX_LIFETIME;
     $LOGGER->info("Lock file {}: {}", $LOCKFILE_LIFETIME === null ? 'NOT EXISTS' : 'EXISTS', $LOCKFILE->getRelPath());
     if ($LOCKFILE_LIFETIME !== null) {
         $LOGGER->info('Last modified: {} seconds ago. Max process delay: {} seconds.', $LOCKFILE_LIFETIME, $MAX_LIFETIME);
         //
     }
     if (!$NED_PROCESS) {
         $LOGGER->info('Skip execution.');
         //Отпустим лок
         PsLock::unlock();
         //Выходим
         return $this->executed;
         //---
     }
     //Обновим время последнего выполнения
     $LOCKFILE->touch();
     //Отпустим лок, так как внутри он может потребоваться для выполнения других действий, например для перестройки спрайтов
     PsLock::unlock();
     $LOGGER->info();
     $LOGGER->info('External process execution started...');
     //Запускаем режим неограниченного выполнения
     PsUtil::startUnlimitedMode();
     //Начинаем выполнение
     $this->executed = true;
     //Создаём профайлер
     $PROFILER = PsProfiler::inst(__CLASS__);
     //Создадим конфиг выполнения процесса
     $config = new PsCronProcessConfig();
     //Пробегаемся по процессам и выполняем. При первой ошибке - выходим.
     foreach ($processes as $class) {
         $LOGGER->info('Executing cron process {}', $class);
         $PROFILER->start($class);
         try {
             $inst = new $class();
             $inst->onCron($config);
             $secundomer = $PROFILER->stop();
             $LOGGER->info(" > Cron process '{}' executed in {} seconds", $class, $secundomer->getTotalTime());
         } catch (Exception $ex) {
             $PROFILER->stop();
             $LOGGER->info(" > Cron process '{}' execution error: '{}'", $class, $ex->getMessage());
         }
     }
     $LOGGER->info('Removing cron lock file.');
     $LOCKFILE->remove();
     return $this->executed;
 }
Example #3
0
 protected function __construct()
 {
     $this->LOGGER = PsLogger::inst(__CLASS__);
     $this->PROFILER = PsProfiler::inst(__CLASS__);
     $this->CACHE = SimpleDataCache::inst();
     $this->DM = DirManager::autoNoDel(DirManager::DIR_FORMULES);
 }