Skip to content

Commit

Permalink
WIP: Implementing subprocesses
Browse files Browse the repository at this point in the history
  • Loading branch information
christianbader committed May 7, 2024
1 parent 01f15c2 commit 7ddaafa
Show file tree
Hide file tree
Showing 4 changed files with 276 additions and 98 deletions.
216 changes: 216 additions & 0 deletions src/Command/DoPopulateIndex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php

declare(strict_types=1);

namespace Valantic\ElasticaBridgeBundle\Command;

use Elastica\Index as ElasticaIndex;
use Pimcore\Model\Element\AbstractElement;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Valantic\ElasticaBridgeBundle\Document\DocumentInterface;
use Valantic\ElasticaBridgeBundle\Exception\Command\DocumentFailedException;
use Valantic\ElasticaBridgeBundle\Index\IndexInterface;
use Valantic\ElasticaBridgeBundle\Repository\ConfigurationRepository;
use Valantic\ElasticaBridgeBundle\Repository\DocumentRepository;
use Valantic\ElasticaBridgeBundle\Repository\IndexRepository;
use Valantic\ElasticaBridgeBundle\Service\DocumentHelper;

class DoPopulateIndex extends BaseCommand
{
private const OPTION_CONFIG = 'config';
private const OPTION_INDEX = 'index';
private const OPTION_BATCH_NUMBER = 'batch-number';
private const OPTION_LISTING_COUNT = 'listing-count';
private const OPTION_DOCUMENT = 'document';

public function __construct(
private readonly IndexRepository $indexRepository,
private readonly DocumentRepository $documentRepository,
private readonly DocumentHelper $documentHelper,
private readonly ConfigurationRepository $configurationRepository,
) {
parent::__construct();
}

protected function configure(): void
{
$this->setName(self::COMMAND_NAMESPACE . 'do-populate-index')
->setHidden(true)
->setDescription('[INTERNAL]')
->addOption(self::OPTION_CONFIG, mode: InputOption::VALUE_REQUIRED)
->addOption(self::OPTION_INDEX, mode: InputOption::VALUE_REQUIRED)
->addOption(self::OPTION_BATCH_NUMBER, mode: InputOption::VALUE_REQUIRED)
->addOption(self::OPTION_LISTING_COUNT, mode: InputOption::VALUE_REQUIRED)
->addOption(self::OPTION_DOCUMENT, mode: InputOption::VALUE_REQUIRED)
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$indexConfig = $this->getIndex();

if (!$indexConfig instanceof IndexInterface) {
return self::FAILURE;
}

$index = $indexConfig->getBlueGreenInactiveElasticaIndex();
$success = $this->populateIndex($indexConfig, $index);

if (!$success) {
return self::FAILURE;
}

return self::SUCCESS;
}

private function getIndex(): ?IndexInterface
{
foreach ($this->indexRepository->flattenedAll() as $indexConfig) {
if ($indexConfig->getName() === $this->input->getOption(self::OPTION_CONFIG)) {
return $indexConfig;
}
}

return null;
}

private function populateIndex(IndexInterface $indexConfig, ElasticaIndex $esIndex): bool
{
ProgressBar::setFormatDefinition('custom', "%percent%%\t%remaining%\t%memory%\n%message%");

$batchNumber = (int) $this->input->getOption(self::OPTION_BATCH_NUMBER);
$listingCount = (int) $this->input->getOption(self::OPTION_LISTING_COUNT);

$progressBar = new ProgressBar($this->output, $listingCount > 0 ? $listingCount : 1);
$progressBar->setMessage('');
$progressBar->setFormat('custom');

$progressBar->setProgress((int) $batchNumber * $indexConfig->getBatchSize());

Check failure on line 91 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Casting to int something that's already int.

Check failure on line 91 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Casting to int something that's already int.

Check failure on line 91 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Casting to int something that's already int.

Check failure on line 91 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Casting to int something that's already int.

$allowedDocuments = $indexConfig->getAllowedDocuments();
$document = $this->input->getOption(self::OPTION_DOCUMENT);

foreach ($allowedDocuments as $allowedDocument) {
if ($allowedDocument === $document) {
$allowedDocument = $document;

break;
}
}

$progressBar->setMessage($document);

$documentInstance = $this->documentRepository->get($allowedDocument);

Check failure on line 106 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Variable $allowedDocument might not be defined.

Check failure on line 106 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Variable $allowedDocument might not be defined.

Check failure on line 106 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Variable $allowedDocument might not be defined.

Check failure on line 106 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Variable $allowedDocument might not be defined.

if (!$indexConfig->shouldIndexInSubprocesses()) {
$numberOfBatches = ceil($listingCount / $indexConfig->getBatchSize());

for ($batchNumber = 0; $batchNumber < $numberOfBatches; $batchNumber++) {

Check failure on line 111 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

For loop initial assignment overwrites variable $batchNumber.

Check failure on line 111 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

For loop initial assignment overwrites variable $batchNumber.

Check failure on line 111 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

For loop initial assignment overwrites variable $batchNumber.

Check failure on line 111 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

For loop initial assignment overwrites variable $batchNumber.
$success = $this->doPopulateIndex($esIndex, $documentInstance, $indexConfig, $progressBar, $document, $batchNumber);

if (!$success) {
return false;
}
}

return true;
} else {
return $this->doPopulateIndex($esIndex, $documentInstance, $indexConfig, $progressBar, $document, $batchNumber);
}
}

private function doPopulateIndex(

Check failure on line 125 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Method Valantic\ElasticaBridgeBundle\Command\DoPopulateIndex::doPopulateIndex() has parameter $documentInstance with generic interface Valantic\ElasticaBridgeBundle\Document\DocumentInterface but does not specify its types: TElement

Check failure on line 125 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Method Valantic\ElasticaBridgeBundle\Command\DoPopulateIndex::doPopulateIndex() has parameter $documentInstance with generic interface Valantic\ElasticaBridgeBundle\Document\DocumentInterface but does not specify its types: TElement

Check failure on line 125 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Method Valantic\ElasticaBridgeBundle\Command\DoPopulateIndex::doPopulateIndex() has parameter $documentInstance with generic interface Valantic\ElasticaBridgeBundle\Document\DocumentInterface but does not specify its types: TElement

Check failure on line 125 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Method Valantic\ElasticaBridgeBundle\Command\DoPopulateIndex::doPopulateIndex() has parameter $documentInstance with generic interface Valantic\ElasticaBridgeBundle\Document\DocumentInterface but does not specify its types: TElement
ElasticaIndex $esIndex,
DocumentInterface $documentInstance,
IndexInterface $indexConfig,
ProgressBar $progressBar,
string $document,
int $batchNumber,
): bool {
try {
$listing = $documentInstance->getListingInstance($indexConfig);
$listing->setOffset($batchNumber * $indexConfig->getBatchSize());
$listing->setLimit($indexConfig->getBatchSize());

foreach ($listing->getData() ?? [] as $dataObject) {
try {
$progressBar->advance();

if (!$documentInstance->shouldIndex($dataObject)) {
continue;
}

$esDocuments[] = $this->documentHelper->elementToDocument($documentInstance, $dataObject);

Check failure on line 146 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Implicit array creation is not allowed - variable $esDocuments might not exist.

Check failure on line 146 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Implicit array creation is not allowed - variable $esDocuments might not exist.

Check failure on line 146 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Implicit array creation is not allowed - variable $esDocuments might not exist.

Check failure on line 146 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Implicit array creation is not allowed - variable $esDocuments might not exist.
} catch (\Throwable $throwable) {
$this->displayDocumentError($indexConfig, $document, $dataObject, $throwable);

if (!$this->configurationRepository->shouldSkipFailingDocuments()) {
throw new DocumentFailedException($throwable);
}
}
}

if (count($esDocuments) > 0) {

Check failure on line 156 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Variable $esDocuments might not be defined.

Check failure on line 156 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Variable $esDocuments might not be defined.

Check failure on line 156 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Variable $esDocuments might not be defined.

Check failure on line 156 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Variable $esDocuments might not be defined.
$esIndex->addDocuments($esDocuments);
$esDocuments = [];
}

if ($indexConfig->refreshIndexAfterEveryDocumentWhenPopulating()) {
$esIndex->refresh();
}
} catch (\Throwable $throwable) {
$this->displayIndexError($indexConfig, $throwable);

return false;
} finally {
if (isset($documentInstance)) {

Check failure on line 169 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Variable $documentInstance in isset() always exists and is not nullable.

Check failure on line 169 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.1 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Variable $documentInstance in isset() always exists and is not nullable.

Check failure on line 169 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-lowest) on ubuntu-latest)

Variable $documentInstance in isset() always exists and is not nullable.

Check failure on line 169 in src/Command/DoPopulateIndex.php

View workflow job for this annotation

GitHub Actions / phpstan (PHP 8.2 with Pimcore ^11.0 (prefer-stable) on ubuntu-latest)

Variable $documentInstance in isset() always exists and is not nullable.
$this->documentHelper->setTenantIfNeeded($documentInstance, $indexConfig);
}
}

return true;
}

private function displayDocumentError(
IndexInterface $indexConfig,
string $document,
AbstractElement $dataObject,
\Throwable $throwable,
): void {
$this->output->writeln('');
$this->output->writeln(sprintf(
'<fg=red;options=bold>Error while populating index %s, processing documents of type %s, last processed element ID %s.</>',
$indexConfig::class,
$document,
$dataObject->getId()
));
$this->displayThrowable($throwable);
}

private function displayIndexError(IndexInterface $indexConfig, \Throwable $throwable): void
{
$this->output->writeln('');
$this->output->writeln(sprintf(
'<fg=red;options=bold>Error while populating index %s.</>',
$indexConfig::class,
));

$this->displayThrowable($throwable);
}

private function displayThrowable(\Throwable $throwable): void
{
$this->output->writeln('');
$this->output->writeln(sprintf('In %s line %d', $throwable->getFile(), $throwable->getLine()));
$this->output->writeln('');

$this->output->writeln($throwable->getMessage());
$this->output->writeln('');

$this->output->writeln($throwable->getTraceAsString());
$this->output->writeln('');
}
}

0 comments on commit 7ddaafa

Please sign in to comment.