| Current File : /home/jvzmxxx/wiki/extensions/Flow/includes/Search/Updaters/AbstractUpdater.php |
<?php
namespace Flow\Search\Updaters;
use Flow\Container;
use Flow\Exception\FlowException;
use Flow\Model\AbstractRevision;
use Flow\RevisionActionPermissions;
use Flow\Search\Connection;
use Flow\Search\Iterators\AbstractIterator;
use MWExceptionHandler;
abstract class AbstractUpdater {
/**
* @var AbstractIterator
*/
public $iterator;
/**
* @var RevisionActionPermissions
*/
protected $permissions;
/**
* @var Connection
*/
protected $connection;
/**
* @param AbstractIterator $iterator
* @param RevisionActionPermissions $permissions
*/
public function __construct( AbstractIterator $iterator, RevisionActionPermissions $permissions ) {
$this->iterator = $iterator;
$this->permissions = $permissions;
$this->connection = Container::get( 'search.connection' );
}
/**
* @return string One of the Connection::*_TYPE_NAME constants
*/
abstract public function getTypeName();
/**
* @param AbstractRevision $revision
* @return \Elastica\Document
*/
abstract public function buildDocument( AbstractRevision $revision );
/**
* @param string|null $shardTimeout Timeout in Elasticsearch time format (1m, 15s, ...)
* @param int|null $clientSideTimeout
* @param int $batchSize
* @return int
*/
public function updateRevisions( $shardTimeout = null, $clientSideTimeout = null, $batchSize = 50 ) {
if ( $clientSideTimeout !== null ) {
$this->connection->setTimeout( $clientSideTimeout );
}
$documents = array();
$count = 0;
foreach ( $this->iterator as $revision ) {
try {
$documents[] = $this->buildDocument( $revision );
$count++;
} catch ( FlowException $e ) {
// just ignore revisions that fail to build document...
wfWarn( __METHOD__ . ': Failed to build document for ' . $revision->getRevisionId()->getAlphadecimal() . ': ' . $e->getMessage());
MWExceptionHandler::logException( $e );
}
// send documents in small batches
if ( count( $documents ) > $batchSize ) {
$this->sendDocuments( $documents, $shardTimeout );
$documents = array();
}
}
if ( $documents ) {
// send remaining documents
$this->sendDocuments( $documents, $shardTimeout );
}
return $count;
}
/**
* @param \Elastica\Document[] $documents
* @param string|null $shardTimeout Timeout in Elasticsearch time format (1m, 15s, ...)
*/
protected function sendDocuments( array $documents, $shardTimeout = null ) {
if ( count( $documents ) === 0 ) {
return;
}
try {
// addDocuments (notice plural) is the bulk api
$bulk = new \Elastica\Bulk( $this->connection->getClient() );
if ( $shardTimeout !== null ) {
$bulk->setShardTimeout( $shardTimeout );
}
$index = $this->connection->getFlowIndex( wfWikiID() );
$type = $index->getType( $this->getTypeName() );
$bulk->setType( $type );
$bulk->addDocuments( $documents );
$bulk->send();
} catch ( \Exception $e ) {
$documentIds = array_map( function( $doc ) {
return $doc->getId();
}, $documents );
wfWarn( __METHOD__ . ': Failed updating documents (' . implode( ',', $documentIds ) . '): ' . $e->getMessage() );
}
}
}