includes/Sanity/MultiClusterRemediatorHelper.php
<?php
namespace CirrusSearch\Sanity;
use InvalidArgumentException;
/**
* Helper to maintain the association with Remediators and theirs corresponding
* BufferedRemediator.
* When calling sendBatch this class evaluates if all action scheduled to the
* BufferedRemediator are the same and send them to the all cluster remediator.
* The aim is to minimize the number of generated LinksUpdate jobs in a setup
* where there are many clusters. If the same elements are to be verified on
* all the clusters then it is equivalent and more efficient to send these
* elements to all clusters using the [ "cluster" => null ] job param as some
* steps (link counting) will be shared accross all the clusters as opposed
* to sending a LinksUpdate job per cluster.
*/
class MultiClusterRemediatorHelper {
/** @var Remediator[] */
private $perClusterRemediators;
/** @var AllClustersQueueingRemediator */
private $allClusterRemediator;
/** @var BufferedRemediator[] */
private $perClusterBufferedRemediator;
/**
* @param Remediator[] $perClusterRemediators
* @param BufferedRemediator[] $perClusterBufferedRemediator
* @param AllClustersQueueingRemediator $allClusterRemediator
* @see \CirrusSearch\Job\CirrusGenericJob::decideClusters()
*/
public function __construct(
array $perClusterRemediators,
array $perClusterBufferedRemediator,
AllClustersQueueingRemediator $allClusterRemediator
) {
if ( array_keys( $perClusterRemediators ) != array_keys( $perClusterBufferedRemediator ) ) {
throw new InvalidArgumentException( '$perClusterRemediators and $perClusterBufferedRemediator must have the same keys' );
}
$this->perClusterRemediators = $perClusterRemediators;
$this->perClusterBufferedRemediator = $perClusterBufferedRemediator;
$this->allClusterRemediator = $allClusterRemediator;
}
/**
* Evaluate if all BufferedRemediator contain the same elements and replay
* the recorded actions to the all cluster remediator or to their corresponding
* remediators otherwize.
*/
public function sendBatch() {
$allSame = true;
$firstRemediator = null;
foreach ( $this->perClusterBufferedRemediator as $remediator ) {
if ( $firstRemediator === null ) {
$firstRemediator = $remediator;
} elseif ( !$remediator->hasSameActions( $firstRemediator ) ) {
$allSame = false;
break;
}
}
if ( $allSame && $this->allClusterRemediator->canSendOptimizedJob( array_keys( $this->perClusterRemediators ) ) ) {
$firstRemediator->replayOn( $this->allClusterRemediator );
} else {
foreach ( $this->perClusterBufferedRemediator as $cluster => $remediator ) {
$remediator->replayOn( $this->perClusterRemediators[$cluster] );
}
}
foreach ( $this->perClusterBufferedRemediator as $remediator ) {
$remediator->resetActions();
}
}
}