task = NULL; $this->shedulerPID = NULL; $this ->addArgument('task_id', InputArgument::REQUIRED, 'The task_id to run') ->addOption( 'runner', 'r', InputOption::VALUE_REQUIRED, 'The name of the runner (manual, scheduler...)', task_abstract::RUNNER_MANUAL ) ->addOption( 'ttyloglevel', 't', InputOption::VALUE_REQUIRED, 'threshold : (DEBUG|INFO|WARNING|ERROR|CRITICAL|ALERT)', '' ) ->setDescription('Run task'); return $this; } public function sig_handler($signo) { if ($this->task) { $this->task->log(sprintf("signal %s received", $signo)); $this->task->setRunning(false); } } protected function doExecute(InputInterface $input, OutputInterface $output) { if (!$this->container['phraseanet.configuration-tester']->isInstalled()) { return self::EXITCODE_SETUP_ERROR; } $task_id = (int) $input->getArgument('task_id'); if ($task_id <= 0 || strlen($task_id) !== strlen($input->getArgument('task_id'))) { throw new \RuntimeException('Argument must be an Id.'); } $task_manager = $this->container['task-manager']; $logger = $task_manager->getLogger(); if ($input->getOption('runner') === task_abstract::RUNNER_MANUAL) { $schedStatus = $task_manager->getSchedulerState(); if ($schedStatus && $schedStatus['status'] == task_abstract::STATE_STARTED && $schedStatus['pid']) { $this->shedulerPID = $schedStatus['pid']; } $runner = task_abstract::RUNNER_MANUAL; } else { $runner = task_abstract::RUNNER_SCHEDULER; $schedStatus = $task_manager->getSchedulerState(); if ($schedStatus && $schedStatus['status'] == task_abstract::STATE_STARTED && $schedStatus['pid']) { $this->shedulerPID = $schedStatus['pid']; } } if ($input->getOption('verbose')) { $this->container['monolog']->pushHandler(new StreamHandler('php://stdout')); } $logfile = __DIR__ . '/../../../../logs/task_' . $task_id . '.log'; $this->container['monolog']->pushHandler(new RotatingFileHandler($logfile, 10)); $this->task = $task_manager->getTask($task_id, $this->container['monolog']); $lib2v = array( 'DEBUG' => \task_abstract::LOG_DEBUG, 'INFO' => \task_abstract::LOG_INFO, 'WARNING' => \task_abstract::LOG_WARNING, 'ERROR' => \task_abstract::LOG_ERROR, 'CRITICAL' => \task_abstract::LOG_CRITICAL, 'ALERT' => \task_abstract::LOG_ALERT ); $tmpTask = $task_manager->getTask($task_id, null); $taskname = $tmpTask->getName(); unset($tmpTask); if (($ttyloglevel = strtoupper($input->getOption('ttyloglevel'))) != '') { if (!array_key_exists($ttyloglevel, $lib2v)) { throw(new RuntimeException(sprintf( "Bad value '%s' for option loglevel\nuse DEBUG|INFO|WARNING|ERROR|CRITICAL|ALERT", $ttyloglevel)) ); } $handler = new StreamHandler("php://stdout", $lib2v[$ttyloglevel]); $logger->pushHandler($handler); } $logfile = __DIR__ . '/../../../../logs/task_' . $task_id . '.log'; $handler = new RotatingFileHandler($logfile, 10); $logger->pushHandler($handler); $this->task = $task_manager->getTask($task_id, $logger); register_tick_function(array($this, 'tick_handler'), true); declare(ticks = 1); if (function_exists('pcntl_signal')) { pcntl_signal(SIGTERM, array($this, 'sig_handler')); pcntl_signal(SIGINT, array($this, 'sig_handler')); } try { $this->task->run($runner); } catch (Exception $e) { $this->task->log(sprintf("taskrun : exception from 'run()', %s \n", $e->getMessage())); return($e->getCode()); } if ($input->getOption('runner') === task_abstract::RUNNER_MANUAL) { $runner = task_abstract::RUNNER_MANUAL; } } public function tick_handler() { static $start; if ($start === null) { $start = time(); } if (time() - $start > 0) { if ($this->shedulerPID) { if (function_exists('posix_kill') && !posix_kill($this->shedulerPID, 0)) { if (method_exists($this->task, 'signal')) { $this->task->signal('SIGNAL_SCHEDULER_DIED'); } else { $this->task->setState(task_abstract::STATE_TOSTOP); } } $start = time(); } } } }