jenkins-bot has submitted this change and it was merged.
Change subject: (Bug 47482) Update redis in bulk onTransactionIdle
......................................................................
(Bug 47482) Update redis in bulk onTransactionIdle
Change I00107ffc9 in mediawiki/core makes WikiPage::updateCategoryCounts defer
work to a callback function which executes at the end of the current
transaction, if one is open. This means that LinksUpdateComplete is no longer
guaranteed to run after CategoryAfterPageAdded / CategoryAfterPageRemoved.
Consequently we can no longer rely on it for batch-processing all pending
updates.
This change uses a different mechanism to defer batch processing of redis
updates to a Database->onTransactionIdle callback.
Change-Id: Ib073661c267cbabbe2ab2245224afd12b8784fca
---
M GettingStarted.php
M RedisCategorySync.php
2 files changed, 37 insertions(+), 23 deletions(-)
Approvals:
Aaron Schulz: Looks good to me, but someone else must approve
Mattflaschen: Looks good to me, approved
jenkins-bot: Verified
diff --git a/GettingStarted.php b/GettingStarted.php
index d8a5308..45f9bf1 100644
--- a/GettingStarted.php
+++ b/GettingStarted.php
@@ -164,7 +164,6 @@
$wgHooks[ 'RecentChange_save' ][] = 'GettingStartedHooks::onRecentChange_save';
$wgHooks[ 'CategoryAfterPageAdded' ][] =
'RedisCategorySync::onCategoryAfterPageAdded';
$wgHooks[ 'CategoryAfterPageRemoved' ][] =
'RedisCategorySync::onCategoryAfterPageRemoved';
-$wgHooks[ 'LinksUpdateComplete' ][] =
'RedisCategorySync::onLinksUpdateComplete';
$wgHooks[ 'ListDefinedTags' ][] = 'GettingStartedHooks::onListDefinedTags';
$wgHooks[ 'MakeGlobalVariablesScript' ][] =
'GettingStartedHooks::onMakeGlobalVariablesScript';
$wgHooks[ 'BeforeCreateEchoEvent' ][] =
'GettingStartedHooks::onBeforeCreateEchoEvent';
diff --git a/RedisCategorySync.php b/RedisCategorySync.php
index 18e2bc2..041a84f 100644
--- a/RedisCategorySync.php
+++ b/RedisCategorySync.php
@@ -22,6 +22,10 @@
/** @var array: arrays of [Category, WikiPage] removals to process. **/
public static $removals = array();
+ /** @var bool: whether or not an update callback has been registered.
**/
+ public static $callbackSet = false;
+
+
/**
* Acquire a Redis connection.
* @return Redis|bool Redis client or false.
@@ -87,6 +91,7 @@
public static function onCategoryAfterPageAdded( Category $category,
WikiPage $page ) {
if ( self::isUpdateRelevant( $category, $page ) ) {
self::$additions[] = array( $category, $page );
+ self::setCallback();
}
return true;
}
@@ -98,39 +103,49 @@
public static function onCategoryAfterPageRemoved( Category $category,
WikiPage $page ) {
if ( self::isUpdateRelevant( $category, $page ) ) {
self::$removals[] = array( $category, $page );
+ self::setCallback();
}
return true;
}
/**
- * @param LinksUpdate &$linksUpdate
+ * Register a callback function that will perform all redis updates once
+ * the current transaction completes.
+ * @return bool True if callback was set, false if it was set already.
*/
- public static function onLinksUpdateComplete( $linksUpdate ) {
- if ( !count( self::$additions ) && !count( self::$removals ) ) {
- return true;
+ public static function setCallback() {
+ if ( self::$callbackSet ) {
+ return false;
}
+ self::$callbackSet = true;
- $conn = self::getClient();
- if ( !$conn ) {
- wfDebugLog( 'GettingStarted', "Unable to acquire redis
connection.\n" );
- return true;
- }
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->onTransactionIdle( function () {
+ // Any category updates that happen after this will
require an
+ // additional run of the callback.
+ RedisCategorySync::$callbackSet = false;
- try {
- $redis = $conn->multi( Redis::PIPELINE );
- foreach( self::$additions as $addition ) {
- list( $category, $page ) = $addition;
- $redis->sAdd( self::makeCategoryKey( $category
), $page->getId() );
+ $conn = RedisCategorySync::getClient();
+ if ( !$conn ) {
+ wfDebugLog( 'GettingStarted', "Unable to
acquire redis connection.\n" );
+ return;
}
- foreach( self::$removals as $removal ) {
- list( $category, $page ) = $removal;
- $redis->sRem( self::makeCategoryKey( $category
), $page->getId() );
- }
- $redis->exec();
- } catch ( RedisException $e ) {
- wfDebugLog( 'GettingStarted', 'Redis exception: ' .
$e->getMessage() . "\n" );
- }
+ try {
+ $redis = $conn->multi( Redis::PIPELINE );
+ while ( RedisCategorySync::$additions ) {
+ list( $category, $page ) = array_pop(
RedisCategorySync::$additions );
+ $redis->sAdd(
RedisCategorySync::makeCategoryKey( $category ), $page->getId() );
+ }
+ while ( RedisCategorySync::$removals ) {
+ list( $category, $page ) = array_pop(
RedisCategorySync::$removals );
+ $redis->sRem(
RedisCategorySync::makeCategoryKey( $category ), $page->getId() );
+ }
+ $redis->exec();
+ } catch ( RedisException $e ) {
+ wfDebugLog( 'GettingStarted', 'Redis exception:
' . $e->getMessage() . "\n" );
+ }
+ } );
return true;
}
}
--
To view, visit https://gerrit.wikimedia.org/r/60233
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib073661c267cbabbe2ab2245224afd12b8784fca
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/GettingStarted
Gerrit-Branch: master
Gerrit-Owner: Ori.livneh <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Mattflaschen <[email protected]>
Gerrit-Reviewer: Ori.livneh <[email protected]>
Gerrit-Reviewer: Spage <[email protected]>
Gerrit-Reviewer: Swalling <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits