* DeferrableUpdate classes can implement MergeableUpdate.
Duplicate updates will be merged via the merge() method.
* Make SquidUpdate support merge() so that duplicate URL
purges are now caught accross the entire pre-send request
execution.
Change-Id: Idffdd3e71d89e4a0f28281e65a881113caae497c
'MergeHistoryPager' => __DIR__ . '/includes/specials/SpecialMergeHistory.php',
'MergeLogFormatter' => __DIR__ . '/includes/logging/MergeLogFormatter.php',
'MergeMessageFileList' => __DIR__ . '/maintenance/mergeMessageFileList.php',
+ 'MergeableUpdate' => __DIR__ . '/includes/deferred/MergeableUpdate.php',
'Message' => __DIR__ . '/includes/Message.php',
'MessageBlobStore' => __DIR__ . '/includes/cache/MessageBlobStore.php',
'MessageCache' => __DIR__ . '/includes/cache/MessageCache.php',
private static function push( array &$queue, DeferrableUpdate $update ) {
global $wgCommandLineMode;
- array_push( $queue, $update );
+ if ( $update instanceof MergeableUpdate ) {
+ $class = get_class( $update ); // fully-qualified class
+ if ( isset( $queue[$class] ) ) {
+ /** @var $existingUpdate MergeableUpdate */
+ $existingUpdate = $queue[$class];
+ $existingUpdate->merge( $update );
+ } else {
+ $queue[$class] = $update;
+ }
+ } else {
+ $queue[] = $update;
+ }
+
if ( self::$forceDeferral ) {
return; // do not run
}
--- /dev/null
+<?php
+
+/**
+ * Interface that deferrable updates can implement. DeferredUpdates uses this to merge
+ * all pending updates of PHP class into a single update by calling merge().
+ *
+ * @since 1.27
+ */
+interface MergeableUpdate {
+ /**
+ * Merge this update with $update
+ *
+ * @param MergeableUpdate $update Update of the same class type
+ */
+ function merge( MergeableUpdate $update );
+}
* @ingroup Cache
*/
+use Wikimedia\Assert\Assert;
+
/**
* Handles purging appropriate Squid URLs given a title (or titles)
* @ingroup Cache
*/
-class SquidUpdate implements DeferrableUpdate {
+class SquidUpdate implements DeferrableUpdate, MergeableUpdate {
/** @var string[] Collection of URLs to purge */
protected $urls = array();
* @param string[] $urlArr Collection of URLs to purge
*/
public function __construct( array $urlArr ) {
- // Remove duplicate URLs from list
- $this->urls = array_unique( $urlArr );
+ $this->urls = $urlArr;
}
/**
* @deprecated 1.27
*/
public static function newSimplePurge( Title $title ) {
- $urlArr = $title->getSquidURLs();
-
- return new SquidUpdate( $urlArr );
+ return new SquidUpdate( $title->getSquidURLs() );
}
/**
self::purge( $this->urls );
}
+ public function merge( MergeableUpdate $update ) {
+ /** @var SquidUpdate $update */
+ Assert::parameterType( __CLASS__, $update, '$update' );
+
+ $this->urls = array_merge( $this->urls, $update->urls );
+ }
+
/**
* Purges a list of Squids defined in $wgSquidServers.
* $urlArr should contain the full URLs to purge as values
return;
}
+ // Remove duplicate URLs from list
+ $urlArr = array_unique( $urlArr );
+
wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) );
if ( $wgHTCPRouting ) {
}
if ( $wgSquidServers ) {
- // Remove duplicate URLs
- $urlArr = array_unique( $urlArr );
// Maximum number of parallel connections per squid
$maxSocketsPerSquid = 8;
// Number of requests to send per socket
* @throws MWException
* @param string[] $urlArr Collection of URLs to purge
*/
- protected static function HTCPPurge( array $urlArr ) {
+ private static function HTCPPurge( array $urlArr ) {
global $wgHTCPRouting, $wgHTCPMulticastTTL;
// HTCP CLR operation
$wgHTCPMulticastTTL );
}
- // Remove duplicate URLs from collection
- $urlArr = array_unique( $urlArr );
// Get sequential trx IDs for packet loss counting
$ids = UIDGenerator::newSequentialPerNodeIDs(
'squidhtcppurge', 32, count( $urlArr ), UIDGenerator::QUICK_VOLATILE
<?php
-/**
- * @group DeferredUpdates
- */
class DeferredUpdatesTest extends MediaWikiTestCase {
public function testDoUpdatesWeb() {
$this->setMwGlobals( 'wgCommandLineMode', false );
--- /dev/null
+<?php
+
+class SquidUpdatesTest extends MediaWikiTestCase {
+ public function testPurgeMergeWeb() {
+ $this->setMwGlobals( 'wgCommandLineMode', false );
+
+ $urls1 = array();
+ $title = Title::newMainPage();
+ $urls1[] = $title->getCanonicalURL( '?x=1' );
+ $urls1[] = $title->getCanonicalURL( '?x=2' );
+ $urls1[] = $title->getCanonicalURL( '?x=3' );
+ $update1 = new SquidUpdate( $urls1 );
+ DeferredUpdates::addUpdate( $update1 );
+
+ $urls2 = array();
+ $urls2[] = $title->getCanonicalURL( '?x=2' );
+ $urls2[] = $title->getCanonicalURL( '?x=3' );
+ $urls2[] = $title->getCanonicalURL( '?x=4' );
+ $update2 = new SquidUpdate( $urls2 );
+ DeferredUpdates::addUpdate( $update2 );
+
+ $wrapper = TestingAccessWrapper::newFromObject( $update1 );
+ $this->assertEquals( array_merge( $urls1, $urls2 ), $wrapper->urls );
+ }
+}