EBernhardson has uploaded a new change for review.
https://gerrit.wikimedia.org/r/281262
Change subject: WIP index archived titles
......................................................................
WIP index archived titles
Change-Id: I25b2ee0f4dd5a28da5087821511d0caead6aa63b
---
M includes/DataSender.php
M includes/Hooks.php
M includes/Job/DeletePages.php
M includes/Updater.php
M maintenance/forceSearchIndex.php
5 files changed, 121 insertions(+), 4 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CirrusSearch
refs/changes/62/281262/1
diff --git a/includes/DataSender.php b/includes/DataSender.php
index ad344d3..63b8f17 100644
--- a/includes/DataSender.php
+++ b/includes/DataSender.php
@@ -243,6 +243,33 @@
return Status::newGood();
}
+ public function sendArchiveUpdates( array $archived ) {
+ $index = $this->connection->getPageType( 'archive' );
+ if ( !$this->areIndexesAvailableForWrites( array( 'archive' ),
true ) ) {
+ return Status::newFatal( 'cirrussearch-indexes-frozen'
);
+ }
+
+ try {
+ $this->start( "indexing {numIds} archived pages", array(
+ 'numIds' => count( $archived ),
+ 'queryType' => 'send_archive_updates',
+ ) );
+ $bulk = new \Elastica\Bulk(
$this->connection->getClient() );
+ $bulk->setType( $index );
+ $bulk->addData( $archived, 'update' );
+ $bulk->send();
+ } catch ( \Elastica\Exception\ExceptionInterface $e ) {
+ $this->failure( $d );
+ $this->failedLog->warning(
+ '@todo a better error message',
+ array( 'exception' => $e )
+ );
+ return Status::newFatal(
'cirrussearch-failed-archive-updates' );
+ }
+
+ return Status::newGood();
+ }
+
/**
* @param string $localSite The wikiId to add/remove from
local_sites_with_dupe
* @param string $indexName The name of the index to perform updates to
diff --git a/includes/Hooks.php b/includes/Hooks.php
index 7b0377f..40cb325 100644
--- a/includes/Hooks.php
+++ b/includes/Hooks.php
@@ -293,7 +293,11 @@
// Note that we must use the article id provided or it'll be
lost in the ether. The job can't
// load it from the title because the page row has already been
deleted.
JobQueueGroup::singleton()->push(
- new Job\DeletePages( $page->getTitle(), array( 'id' =>
$pageId ) )
+ new Job\DeletePages( $page->getTitle(), array(
+ 'id' => $pageId,
+ 'timestamp' => wfTimestampNow(),
+ 'archive' => true,
+ ) )
);
return true;
}
diff --git a/includes/Job/DeletePages.php b/includes/Job/DeletePages.php
index d794977..2cc1c97 100644
--- a/includes/Job/DeletePages.php
+++ b/includes/Job/DeletePages.php
@@ -36,7 +36,23 @@
$updater = $this->createUpdater();
$indexType = isset( $this->params[ 'indexType' ] ) ?
$this->params[ 'indexType' ] : null;
- return $updater->deletePages( array( $this->title ), array(
$this->params[ 'id' ] ),
- $wgCirrusSearchClientSideUpdateTimeout, $indexType );
+ $success = $updater->deletePages(
+ $wgCirrusSearchClientSideUpdateTimeout, $indexType
+ );
+
+ if ( $success && !empty( $this->params['archive'] ) ) {
+ $success = $updater->archivePages(
+ array(
+ array(
+ 'title' => $this->title,
+ 'page' => $this->params['id'],
+ 'timestamp' =>
$this->params['timestamp']
+ ),
+ ),
+ $wgCirrusSearchClientSideUpdateTimeout
+ );
+ }
+
+ return $success;
}
}
diff --git a/includes/Updater.php b/includes/Updater.php
index 38d19cf..597bc74 100644
--- a/includes/Updater.php
+++ b/includes/Updater.php
@@ -260,9 +260,67 @@
// This job type will insert itself into the job queue
// with a delay if writes to ES are currently paused
$job->run();
+
+ return true;
}
/**
+ * @param Title $title
+ * @param array $archived
+ * @param string $clientSideTimeout
+ * @return bool
+ */
+ public function archivePages( $archived, $clientSideTimeout = null ) {
+ $docs = $this->buildArchiveDocuments( $archived );
+ $head = reset( $archived );
+ foreach ( array_chunk( $docs, 10 ) as $chunked ) {
+ $job = new Job\ElasticaWrite(
+ $head['title'],
+ array(
+ 'clientSideTimeout' =>
$clientSideTimeout,
+ 'method' => 'sendArchiveUpdates',
+ 'arguments' => array( $chunked ),
+ 'cluster' => $this->writeToClusterName
+ )
+ );
+ $job->run();
+ }
+
+ return true;
+ }
+
+ private function buildArchiveDocuments( array $archived ) {
+ global $wgCirrusSearchUpdateConflictRetryCount;
+
+ foreach ( $archived as $delete ) {
+ if ( !isset( $delete['title'] ) ) {
+ // These come from pages that still exist, but
are redirects.
+ // This is non-obvious and we probably need a
better way...
+ continue;
+ }
+ // We need some reliable id that can be used to ensure
we
+ // don't do duplicate updates, but that also will not
have
+ // conflicts cross-wiki.
+ $id = implode( ':', array(
+ wfWikiId(),
+ $delete['title']->getNamespace(),
+ $delete['title']->getText(),
+ ) );
+ $id = base64_encode( md5( $id, true ) );
+ $doc = new \Elastica\Document( $id, array(
+ 'namespace' => $delete['title']->getNamespace(),
+ 'title' => $delete['title']->getText(),
+ 'timestamp' => wfTimestamp( TS_ISO_8601,
$delete['timestamp'] )
+ ) );
+ $doc->setDocAsUpsert( true );
+ $doc->setRetryOnConflict(
$wgCirrusSearchUpdateConflictRetryCount );
+
+ $docs[] = $doc;
+ }
+
+ return $docs;
+ }
+ /**
* @param \WikiPage[] $pages
* @param int $flags
* @return \Elastica\Document[]
diff --git a/maintenance/forceSearchIndex.php b/maintenance/forceSearchIndex.php
index ac6af80..277c1fd 100644
--- a/maintenance/forceSearchIndex.php
+++ b/maintenance/forceSearchIndex.php
@@ -44,6 +44,7 @@
public $toDate = null;
public $toId = null;
public $indexUpdates;
+ public $archiveOnly;
public $limit;
public $queue;
public $maxJobs;
@@ -64,6 +65,7 @@
$this->addOption( 'fromId', 'Start indexing at a specific
page_id. Not useful with --deletes.', false, true );
$this->addOption( 'toId', 'Stop indexing at a specific page_id.
Not useful with --deletes or --from or --to.', false, true );
$this->addOption( 'deletes', 'If this is set then just index
deletes, not updates or creates.', false );
+ $this->addOption( 'archiveOnly', 'Don\'t delete pages, only
index them into the archive. Only useful with --deletes', false, true );
$this->addOption( 'limit', 'Maximum number of pages to process
before exiting the script. Default to unlimited.', false, true );
$this->addOption( 'buildChunks', 'Instead of running the script
spit out commands that can be farmed out to ' .
'different processes or machines to rebuild the index.
Works with fromId and toId, not from and to. ' .
@@ -113,6 +115,7 @@
}
$this->toId = $this->getOption( 'toId' );
$this->indexUpdates = !$this->getOption( 'deletes', false );
+ $this->archiveOnly = (bool) $this->getOption( 'archiveOnly',
true );
$this->limit = $this->getOption( 'limit' );
$buildChunks = $this->getOption( 'buildChunks' );
if ( $buildChunks !== null ) {
@@ -224,16 +227,25 @@
} else {
$titlesToDelete = array();
$idsToDelete = array();
+ $archive = array();
foreach( $deletes as $delete ) {
$titlesToDelete[] = $delete[ 'title' ];
$idsToDelete[] = $delete[ 'page' ];
$lastDelete = $delete;
+ $archive[] = array(
+ 'title' => $delete['title'],
+ 'page' => $delete['page'],
+ 'timestamp' =>
$delete['timestamp'],
+ );
}
$minUpdate = $lastDelete[ 'timestamp' ];
$minNamespace = $lastDelete[ 'title'
]->getNamespace();
$minTitle = $lastDelete[ 'title' ]->getText();
$updater = $this->createUpdater();
- $updater->deletePages( $titlesToDelete,
$idsToDelete );
+ $updater->archivePages( $archive );
+ if ( !$this->archiveOnly ) {
+ $updater->deletePages( $titlesToDelete,
$idsToDelete );
+ }
}
$completed += $size;
--
To view, visit https://gerrit.wikimedia.org/r/281262
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I25b2ee0f4dd5a28da5087821511d0caead6aa63b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits