コード例 #1
0
 /**
  * @inheritdoc
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $action = $input->getArgument('action');
     $number = $input->getArgument('number');
     $kicked = $this->manager->kick($action, $number);
     $output->writeln(sprintf('Kicked <info>%d</info> buried <info>%s</info> job(s)', $kicked, $action));
 }
コード例 #2
0
 /**
  * @param OutputInterface $output
  * @param array           $actions
  * @param bool            $empty
  */
 protected function render(OutputInterface $output, array $actions, $empty = false)
 {
     $fields = ['action' => 'name', 'workers' => 'current-watching', 'reserved' => 'current-jobs-reserved', 'ready' => 'current-jobs-ready', 'urgent' => 'current-jobs-urgent', 'delayed' => 'current-jobs-delayed', 'buried' => 'current-jobs-buried'];
     $table = new Table($output);
     $table->setHeaders(array_keys($fields));
     $rows = [];
     foreach ($actions as $action) {
         if (!($stats = $this->manager->getActionStats($action))) {
             if (!$empty) {
                 continue;
             }
             $stats = array_combine(array_values($fields), array_fill(0, sizeof($fields), '-'));
             $stats['name'] = $action;
         }
         $rows[$action] = array_map(function ($field) use($stats) {
             return $stats[$field];
         }, $fields);
     }
     ksort($rows);
     $table->addRows($rows);
     if ($this->lineCount) {
         // move back to the beginning
         $output->write("");
         $output->write(sprintf("[%dA", $this->lineCount));
         // overwrite the complete table before rendering the new one
         $width = $this->getApplication()->getTerminalDimensions()[0];
         $lines = array_fill(0, $this->lineCount, str_pad('', $width, ' '));
         $output->writeln($lines);
         $output->write(sprintf("[%dA", $this->lineCount));
     }
     // render the new table
     $table->render();
     // top table border + header + header border + bottom table border = 4
     $this->lineCount = 4 + sizeof($rows);
 }
コード例 #3
0
 /**
  * @inheritdoc
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $actions = $input->getArgument('action');
     if (empty($actions)) {
         $actions = array_keys($this->manager->getExecutors());
     }
     $states = $input->getOption('state');
     $pheanstalk = $this->manager->getPheanstalk();
     foreach ($actions as $action) {
         try {
             $stats = $pheanstalk->statsTube($action);
             $amount = 0;
             foreach ($states as $state) {
                 $amount += $stats['current-jobs-' . $state];
             }
             $output->writeln(sprintf('Clearing <info>%d %s jobs</info> with <info>%s</info> status', $amount, $action, implode(', ', $states)));
             $this->manager->clear($action, $states);
             $output->writeln(['<info>Done!</info>', '']);
         } catch (ServerException $e) {
             if (false === strpos($e->getMessage(), 'NOT_FOUND')) {
                 throw $e;
             }
         }
     }
 }
コード例 #4
0
 /**
  * @inheritdoc
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $action = $input->getArgument('action');
     $payload = $input->getArgument('payload');
     $output->writeln(sprintf('Performing action <info>%s</info> with payload <info>%s</info>', $action, json_encode($payload, JSON_UNESCAPED_SLASHES)));
     $timeStart = microtime(true) * 1000;
     $memStart = memory_get_usage(true);
     $result = $this->manager->execute($action, $payload);
     $duration = microtime(true) * 1000 - $timeStart;
     $usage = memory_get_usage(true) - $memStart;
     $output->writeln(sprintf('Completed in <comment>%dms</comment> using <comment>%s</comment> with result: <info>%s</info>', $duration, $this->formatBytes($usage), json_encode($result, JSON_UNESCAPED_SLASHES)));
     $this->manager->getDispatcher()->dispatch(WorkerEvents::FLUSH);
 }
コード例 #5
0
 /**
  * @param OutputInterface $output
  * @param string          $action
  * @param int             $limit
  */
 protected function inspect(OutputInterface $output, $action, $limit = null)
 {
     $output->writeln(sprintf('Inspecting jobs for the <info>%s</info> action', $action));
     $this->manager->watchOnly([$action]);
     $jobs = [];
     while ($job = $this->manager->get(1)) {
         $output->writeln(sprintf('<info>%d</info>: <comment>%s</comment>', $job->getId(), $job->getData()));
         $jobs[] = $job;
         if (null !== $limit && sizeof($jobs) >= $limit) {
             break;
         }
     }
     $output->writeln('Releasing the jobs back to the queue, <error>don\'t cancel this action!</error>');
     foreach ($jobs as $job) {
         $stats = $this->manager->getJobStats($job);
         $this->manager->getPheanstalk()->release($job, $stats['pri']);
     }
 }
コード例 #6
0
 /**
  * @param OutputInterface $output
  * @param array           $feeds
  * @param integer         $minutes
  * @param boolean         $force
  *
  * @return integer
  */
 protected function scheduleImports(OutputInterface $output, array $feeds, $minutes, $force = false)
 {
     if (empty($feeds)) {
         return 0;
     }
     $repo = $this->getFeedRepository();
     $manager = $this->importManager;
     $num = 0;
     $factor = $minutes / sizeof($feeds);
     foreach ($feeds as $id => $priority) {
         /** @var Feed $feed */
         $feed = $repo->find($id);
         $offset = round($factor * $num++);
         $date = new \DateTime(sprintf('+%d minutes', $offset));
         $output->writeln(sprintf('Scheduling import for <info>%s</info> feed <info>%d</info> to run at <info>%s</info>', $feed->getOrigin()->getName(), $feed->getId(), $date->format('Y-m-d H:i:s')));
         // schedule all resources
         try {
             $dispatcher = $manager->getEventDispatcher();
             $import = $manager->createImport($feed, $date, $force);
             $reader = $manager->createImportReader($import, $dispatcher, $manager->getReaderOptions($import));
         } catch (\RuntimeException $e) {
             // we could get an exception when a new import cannot be created, for example when an existing import
             // for this feed is still running.
             $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
             continue;
         }
         $output->writeln(sprintf('Created import <info>%d</info>, adding parts...', $import->getId()));
         try {
             while ($reader->getResources()->count()) {
                 $resource = $reader->getResources()->dequeue();
                 $transportConfig = TransportFactory::createConfigFromTransport($resource->getTransport());
                 $manager->createImportPart($import, $transportConfig, $date);
                 $output->writeln(sprintf('=> <comment>%s</comment> (<comment>%d</comment> resources left)', (string) $resource->getTransport(), $reader->getResources()->count()));
             }
         } catch (FeedException $e) {
             $output->writeln(sprintf('<error>%s</error>', $e->getMessage()));
         }
         if ($import->getParts()->count() === 0) {
             $output->writeln('No parts created, finishing import now');
             $manager->startImport($import);
             $manager->finishImport($import);
             continue;
         }
         $output->write('Scheduling jobs for all parts...');
         foreach ($import->getParts() as $part) {
             $delay = $date->getTimestamp() - time();
             if ($delay < 0) {
                 $delay = 0;
             }
             $this->queueManager->addForObject(ImportPartExecutor::NAME, $part, $delay);
         }
         $output->writeln(' <info>done!</info>');
     }
     return 0;
 }
コード例 #7
0
 /**
  * @inheritdoc
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $action = $input->getArgument('action');
     $payload = $input->getArgument('payload');
     $priority = $input->getOption('priority');
     $delay = $input->getOption('delay');
     $ttr = $input->getOption('ttr');
     $dql = $input->getOption('dql');
     if ($payload && $dql) {
         throw new \InvalidArgumentException('You cannot provide both a <comment>payload</comment> and a <comment>--dql</comment> query.');
     }
     if (!empty($payload)) {
         $job = $this->manager->add($action, $payload, $delay, $priority, $ttr);
         $output->writeln(sprintf('Scheduled job <info>%d</info> with payload <info>%s</info>', $job, json_encode($payload)));
         return 0;
     }
     if (empty($dql)) {
         throw new \InvalidArgumentException('You must provide either a <comment>payload</comment> or a <comment>--dql</comment> query.');
     }
     if (!$this->doctrine) {
         $output->writeln('<error>Doctrine is required for the --dql option</error>');
         return 1;
     }
     $doctrine = $this->doctrine->getManager();
     if (!$doctrine instanceof EntityManagerInterface) {
         $output->writeln('<error>Sorry, only Doctrine\'s ORM is supported at this point. You\'re welcome to submit a PR of course!</error>');
         return 1;
     }
     $meta = null;
     $query = $doctrine->createQuery($dql);
     foreach ($query->iterate() as list($entity)) {
         if (!$meta) {
             $meta = $doctrine->getClassMetadata(get_class($entity));
         }
         $job = $this->manager->addForObject($action, $entity, $delay, $priority, $ttr);
         $output->writeln(sprintf('Scheduled job <info>%d</info> for entity <info>%s: %s</info>', $job, json_encode($meta->getIdentifierValues($entity)), $this->entityToString($entity)));
         $doctrine->clear();
     }
     return 0;
 }
コード例 #8
0
 public function testExecuteJobAndNoMoreRetries()
 {
     $action = 'test';
     $executor = $this->getMockForAbstractClass(ExecutorInterface::class);
     $executor->expects($this->any())->method('getName')->will($this->returnValue($action));
     $this->manager->addExecutor($executor);
     $data = [];
     $job = new Job(1234, json_encode($data));
     $stats = ['tube' => $action, 'releases' => 2, 'pri' => PheanstalkInterface::DEFAULT_PRIORITY];
     $this->pheanstalk->expects($this->once())->method('statsJob')->with($job)->will($this->returnValue($stats));
     $this->pheanstalk->expects($this->once())->method('bury')->with($job);
     $executor->expects($this->once())->method('execute')->will($this->throwException(new \Exception('oh noes!')));
     $this->manager->executeJob($job);
 }
コード例 #9
0
 /**
  * @inheritdoc
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $actions = $input->getArgument('action');
     if (empty($actions)) {
         $actions = array_keys($this->manager->getExecutors());
     }
     $states = $input->getOption('state');
     foreach ($actions as $action) {
         $output->writeln(sprintf('Action: <info>%s</info>', $action));
         $table = new Table($output);
         $table->setHeaders(['state', 'id', 'data']);
         foreach ($states as $state) {
             $job = $this->manager->peek($action, $state);
             if (is_null($job)) {
                 $table->addRow([$state, '-', '-']);
             } else {
                 $table->addRow([$state, $job->getId(), $job->getData()]);
             }
         }
         $table->render();
         $output->writeln('');
     }
 }
コード例 #10
0
 /**
  * @param string[] $include
  * @param string[] $exclude
  */
 protected function watchActions(array $include = [], array $exclude = [])
 {
     $actions = array_keys($this->manager->getExecutors());
     if (empty($include)) {
         $include = $actions;
     }
     if (!empty($diff = array_diff($include, $actions))) {
         throw new \InvalidArgumentException(sprintf('Action(s) "%s" are not defined by QueueManager', implode(', ', $diff)));
     }
     if (!empty($diff = array_diff($exclude, $actions))) {
         throw new \InvalidArgumentException(sprintf('Filter(s) "%s" are not defined by QueueManager', implode(', ', $diff)));
     }
     $include = array_diff($include, $exclude);
     if (empty($include)) {
         throw new \InvalidArgumentException('No actions specified to run');
     }
     // watch only these actions
     $this->manager->watchOnly($include);
 }
コード例 #11
0
 /**
  * @param SourceEvent $event
  */
 public function onSourceProcess(SourceEvent $event)
 {
     $this->queueManager->addForObject(SourceProcessExecutor::NAME, $event->getSource());
 }
コード例 #12
0
 /**
  * @param RateLimitEvent $event
  */
 public function onRateLimit(RateLimitEvent $event)
 {
     $payload = [$event->getScraper()->getId(), $event->getUrl()];
     $this->queueManager->add(ScrapeUrlExecutor::NAME, $payload, $event->getRetryDate()->getTimestamp() - time());
 }
コード例 #13
0
 /**
  * @param PartEvent $event
  */
 public function onPartScheduled(PartEvent $event)
 {
     $this->queueManager->addForObject(ImportPartExecutor::NAME, $event->getPart(), null, null, $this->timeToRun);
 }
コード例 #14
0
 /**
  * Schedules a source process job
  *
  * @param SourceInterface $source
  */
 protected function scheduleSourceProcess(SourceInterface $source)
 {
     $this->queueManager->addForObject(SourceProcessExecutor::NAME, $source);
 }
コード例 #15
0
 /**
  * @param ScrapeUrlEvent $event
  */
 public function onScrapeNextUrl(ScrapeUrlEvent $event)
 {
     $this->queueManager->add(ScrapeUrlExecutor::NAME, [$event->getScraper()->getId(), $event->getUrl()]);
 }
コード例 #16
0
 /**
  * @param SourceEvent $event
  */
 public function onScrapeRevisitSource(SourceEvent $event)
 {
     $this->queueManager->addForObject(ScrapeRevisitSourceExecutor::NAME, $event->getSource());
 }