Skip to content

Commit

Permalink
Issue #3463797 by mkalkbrenner: Avoid standard deletes when reindexin…
Browse files Browse the repository at this point in the history
…g if the index is empty
  • Loading branch information
mkalkbrenner committed Jul 25, 2024
1 parent 83f6596 commit 22b48d9
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
23 changes: 23 additions & 0 deletions src/Commands/SearchApiSolrCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,29 @@ public function indexParallel($indexId = NULL, array $options = ['threads' => NU
}
sleep(2);
}

$this->commandHelper->resetEmptyIndexState([$indexId]);
}

/**
* Reset empty index state to FALSE.
*
* Important if drush search-api-solr:index-parallel crashed or has been
* interrupted. That might cause to block deletes on an index for one hour
* unless you run this command.
*
* @param string $indexId
* (optional) A search index ID, or NULL to index items for all enabled
* indexes.
* @param array $options
* (optional) An array of options.
*
* @command search-api-solr:reset-empty-index-state
*
* @default $options []
*/
public function resetEmptyIndexState($indexId = NULL, array $options = []) {
$this->commandHelper->resetEmptyIndexState([$indexId]);
}

}
13 changes: 13 additions & 0 deletions src/Entity/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

class Index extends SearchApiIndex {

const KEEP_EMPTY_INDEX_STATE_SECONDS = 3600;

/**
* {@inheritdoc}
*/
Expand All @@ -19,4 +21,15 @@ public function getLockId(): string {
return parent::getLockId();
}

public function isIndexingEmptyIndex(): bool {
$key = "search_api.index.{$this->id()}.indexing_empty";
$timestamp = \Drupal::state()->get($key, 0);
return (\Drupal::time()->getRequestTime() - $timestamp) < self::KEEP_EMPTY_INDEX_STATE_SECONDS;
}

public function setIndexingEmptyIndex(bool $state): void {
$key = "search_api.index.{$this->id()}.indexing_empty";
\Drupal::state()->set($key, $state ? \Drupal::time()->getRequestTime() : 0);
}

}
5 changes: 5 additions & 0 deletions src/Plugin/search_api/backend/SearchApiSolrBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,11 @@ public function getDocuments(IndexInterface $index, array $items, UpdateQuery $u
* @throws \Drupal\search_api\SearchApiException
*/
public function deleteItems(IndexInterface $index, array $ids) {
/** @var \Drupal\search_api_solr\Entity\Index $index */
if ($index->isIndexingEmptyIndex()) {
return;
}

try {
$index_id = $this->getTargetedIndexId($index);
$site_hash = $this->getTargetedSiteHash($index);
Expand Down
17 changes: 15 additions & 2 deletions src/Utility/SolrCommandHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,14 @@ public function indexParallelCommand(array $indexIds = NULL, $threads = 2, $batc

$ids = [];

/** @var \Drupal\search_api_solr\Entity\Index $index */
foreach ($indexes as $index) {
if (!$index->status() || $index->isReadOnly()) {
continue;
}
$tracker = $index->getTrackerInstance();
$remaining = $tracker->getTotalItemsCount() - $tracker->getIndexedItemsCount();
$indexed = (int) $tracker->getIndexedItemsCount();
$remaining = $tracker->getTotalItemsCount() - $indexed;

if (!$remaining) {
$this->logSuccess($this->t("The index @index is up to date.", ['@index' => $index->label()]));
Expand Down Expand Up @@ -258,12 +260,15 @@ public function indexParallelCommand(array $indexIds = NULL, $threads = 2, $batc
$currentThreads = 1;
}

$index->setIndexingEmptyIndex($indexed === 0);

$arguments = [
'@index' => $index->label(),
'@threads' => $currentThreads,
'@batch_size' => $currentBatchSize,
'@empty' => $index->isIndexingEmptyIndex() ? $this->t('empty') : $this->t('not empty'),
];
$this->logSuccess($this->t("Indexing parallel with @threads threads (@batch_size items per batch run) for the index '@index'.", $arguments));
$this->logSuccess($this->t("Indexing parallel with @threads threads (@batch_size items per batch run) for the index '@index'. The index is @empty", $arguments));

// Create the batch.
try {
Expand Down Expand Up @@ -298,5 +303,13 @@ public function indexParallelCommand(array $indexIds = NULL, $threads = 2, $batc
return $shuffled_ids;
}

public function resetEmptyIndexState(array $indexIds): void {
if ($indexes = $this->loadIndexes($indexIds)) {
/** @var \Drupal\search_api_solr\Entity\Index $index */
foreach ($indexes as $index) {
$index->setIndexingEmptyIndex(FALSE);
}
}
}

}

0 comments on commit 22b48d9

Please sign in to comment.