Index: trunk/phase3/maintenance/importDump.php |
— | — | @@ -209,7 +209,7 @@ |
210 | 210 | } |
211 | 211 | wfWaitForSlaves(); |
212 | 212 | // XXX: Don't let deferred jobs array get absurdly large (bug 24375) |
213 | | - wfDoUpdates( 'commit' ); |
| 213 | + DeferredUpdates::doUpdates( 'commit' ); |
214 | 214 | } |
215 | 215 | |
216 | 216 | function progress( $string ) { |
Index: trunk/phase3/tests/phpunit/suites/UploadFromUrlTestSuite.php |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | } |
16 | 16 | |
17 | 17 | function setUp() { |
18 | | - global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList, |
| 18 | + global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, |
19 | 19 | $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, |
20 | 20 | $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, |
21 | 21 | $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, |
— | — | @@ -41,7 +41,7 @@ |
42 | 42 | |
43 | 43 | |
44 | 44 | $wgEnableParserCache = false; |
45 | | - $wgDeferredUpdateList = array(); |
| 45 | + DeferredUpdates::clearPendingUpdates(); |
46 | 46 | $wgMemc = wfGetMainCache(); |
47 | 47 | $messageMemc = wfGetMessageCacheStorage(); |
48 | 48 | $parserMemc = wfGetParserCacheStorage(); |
Index: trunk/phase3/tests/parser/parserTest.inc |
— | — | @@ -132,7 +132,7 @@ |
133 | 133 | } |
134 | 134 | |
135 | 135 | static function setUp() { |
136 | | - global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList, |
| 136 | + global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, |
137 | 137 | $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, |
138 | 138 | $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, |
139 | 139 | $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, |
— | — | @@ -160,7 +160,7 @@ |
161 | 161 | |
162 | 162 | |
163 | 163 | $wgEnableParserCache = false; |
164 | | - $wgDeferredUpdateList = array(); |
| 164 | + DeferredUpdates::clearPendingUpdates(); |
165 | 165 | $wgMemc = wfGetMainCache(); |
166 | 166 | $messageMemc = wfGetMessageCacheStorage(); |
167 | 167 | $parserMemc = wfGetParserCacheStorage(); |
Index: trunk/phase3/includes/search/SearchUpdate.php |
— | — | @@ -13,7 +13,7 @@ |
14 | 14 | * |
15 | 15 | * @ingroup Search |
16 | 16 | */ |
17 | | -class SearchUpdate { |
| 17 | +class SearchUpdate implements DeferrableUpdate { |
18 | 18 | |
19 | 19 | private $mId = 0, $mNamespace, $mTitle, $mText; |
20 | 20 | private $mTitleWords; |
Index: trunk/phase3/includes/SiteStats.php |
— | — | @@ -220,9 +220,9 @@ |
221 | 221 | } |
222 | 222 | |
223 | 223 | /** |
224 | | - * |
| 224 | + * Class for handling updates to the site_stats table |
225 | 225 | */ |
226 | | -class SiteStatsUpdate { |
| 226 | +class SiteStatsUpdate implements DeferrableUpdate { |
227 | 227 | |
228 | 228 | var $mViews, $mEdits, $mGood, $mPages, $mUsers; |
229 | 229 | |
Index: trunk/phase3/includes/GlobalFunctions.php |
— | — | @@ -2918,35 +2918,11 @@ |
2919 | 2919 | /** |
2920 | 2920 | * Do any deferred updates and clear the list |
2921 | 2921 | * |
2922 | | - * @param $commit String: set to 'commit' to commit after every update to |
2923 | | - * prevent lock contention |
| 2922 | + * @deprecated since 1.19 |
| 2923 | + * @see DeferredUpdates::doUpdate() |
2924 | 2924 | */ |
2925 | 2925 | function wfDoUpdates( $commit = '' ) { |
2926 | | - global $wgDeferredUpdateList; |
2927 | | - |
2928 | | - wfProfileIn( __METHOD__ ); |
2929 | | - |
2930 | | - // No need to get master connections in case of empty updates array |
2931 | | - if ( !count( $wgDeferredUpdateList ) ) { |
2932 | | - wfProfileOut( __METHOD__ ); |
2933 | | - return; |
2934 | | - } |
2935 | | - |
2936 | | - $doCommit = $commit == 'commit'; |
2937 | | - if ( $doCommit ) { |
2938 | | - $dbw = wfGetDB( DB_MASTER ); |
2939 | | - } |
2940 | | - |
2941 | | - foreach ( $wgDeferredUpdateList as $update ) { |
2942 | | - $update->doUpdate(); |
2943 | | - |
2944 | | - if ( $doCommit && $dbw->trxLevel() ) { |
2945 | | - $dbw->commit(); |
2946 | | - } |
2947 | | - } |
2948 | | - |
2949 | | - $wgDeferredUpdateList = array(); |
2950 | | - wfProfileOut( __METHOD__ ); |
| 2926 | + DeferredUpdates::doUpdates( $commit ); |
2951 | 2927 | } |
2952 | 2928 | |
2953 | 2929 | /** |
Index: trunk/phase3/includes/DeferredUpdates.php |
— | — | @@ -0,0 +1,83 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Interface that deferrable updates should implement. Basically required so we |
| 5 | + * can validate input on DeferredUpdates::addUpdate() |
| 6 | + */ |
| 7 | +interface DeferrableUpdate { |
| 8 | + /** |
| 9 | + * Perform the actual work |
| 10 | + */ |
| 11 | + function doUpdate(); |
| 12 | +} |
| 13 | + |
| 14 | +/** |
| 15 | + * Class for mananging the deferred updates. |
| 16 | + */ |
| 17 | +class DeferredUpdates { |
| 18 | + /** |
| 19 | + * Store of updates to be deferred until the end of the request. |
| 20 | + */ |
| 21 | + private static $updates = array(); |
| 22 | + |
| 23 | + /** |
| 24 | + * Add an update to the deferred list |
| 25 | + * @param $update DeferrableUpdate Some object that implements doUpdate() |
| 26 | + */ |
| 27 | + public static function addUpdate( DeferrableUpdate $update ) { |
| 28 | + array_push( self::$updates, $update ); |
| 29 | + } |
| 30 | + |
| 31 | + /** |
| 32 | + * HTMLCacheUpdates are the most common deferred update people use. This |
| 33 | + * is a shortcut method for that. |
| 34 | + * @see HTMLCacheUpdate::__construct() |
| 35 | + */ |
| 36 | + public static function addHTMLCacheUpdate( $title, $table ) { |
| 37 | + self::addUpdate( new HTMLCacheUpdate( $title, $table ) ); |
| 38 | + } |
| 39 | + |
| 40 | + /** |
| 41 | + * Do any deferred updates and clear the list |
| 42 | + * |
| 43 | + * @param $commit String: set to 'commit' to commit after every update to |
| 44 | + * prevent lock contention |
| 45 | + */ |
| 46 | + public static function doUpdates( $commit = '' ) { |
| 47 | + global $wgDeferredUpdateList; |
| 48 | + |
| 49 | + wfProfileIn( __METHOD__ ); |
| 50 | + |
| 51 | + $updates = array_merge( $wgDeferredUpdateList, self::$updates ); |
| 52 | + |
| 53 | + // No need to get master connections in case of empty updates array |
| 54 | + if ( !count( $updates ) ) { |
| 55 | + wfProfileOut( __METHOD__ ); |
| 56 | + return; |
| 57 | + } |
| 58 | + |
| 59 | + $doCommit = $commit == 'commit'; |
| 60 | + if ( $doCommit ) { |
| 61 | + $dbw = wfGetDB( DB_MASTER ); |
| 62 | + } |
| 63 | + |
| 64 | + foreach ( $updates as $update ) { |
| 65 | + $update->doUpdate(); |
| 66 | + |
| 67 | + if ( $doCommit && $dbw->trxLevel() ) { |
| 68 | + $dbw->commit(); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + self::clearPendingUpdates(); |
| 73 | + wfProfileOut( __METHOD__ ); |
| 74 | + } |
| 75 | + |
| 76 | + /** |
| 77 | + * Clear all pending updates without performing them. Generally, you don't |
| 78 | + * want or need to call this. Unit tests need it though. |
| 79 | + */ |
| 80 | + public static function clearPendingUpdates() { |
| 81 | + global $wgDeferredUpdateList; |
| 82 | + $wgDeferredUpdateList = self::$updates = array(); |
| 83 | + } |
| 84 | +} |
Property changes on: trunk/phase3/includes/DeferredUpdates.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 85 | + native |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -49,6 +49,8 @@ |
50 | 50 | 'ContextSource' => 'includes/RequestContext.php', |
51 | 51 | 'Cookie' => 'includes/Cookie.php', |
52 | 52 | 'CookieJar' => 'includes/Cookie.php', |
| 53 | + 'DeferrableUpdate' => 'includes/DeferredUpdates.php', |
| 54 | + 'DeferredUpdates' => 'includes/DeferredUpdates.php', |
53 | 55 | 'DiffHistoryBlob' => 'includes/HistoryBlob.php', |
54 | 56 | 'DjVuImage' => 'includes/DjVuImage.php', |
55 | 57 | 'DoubleReplacer' => 'includes/StringUtils.php', |
Index: trunk/phase3/includes/Wiki.php |
— | — | @@ -377,7 +377,7 @@ |
378 | 378 | // Output everything! |
379 | 379 | $this->context->getOutput()->output(); |
380 | 380 | // Do any deferred jobs |
381 | | - wfDoUpdates( 'commit' ); |
| 381 | + DeferredUpdates::doUpdates( 'commit' ); |
382 | 382 | $this->doJobs(); |
383 | 383 | wfProfileOut( __METHOD__ ); |
384 | 384 | } |
Index: trunk/phase3/includes/cache/HTMLCacheUpdate.php |
— | — | @@ -23,8 +23,7 @@ |
24 | 24 | * |
25 | 25 | * @ingroup Cache |
26 | 26 | */ |
27 | | -class HTMLCacheUpdate |
28 | | -{ |
| 27 | +class HTMLCacheUpdate implements DeferrableUpdate { |
29 | 28 | /** |
30 | 29 | * @var Title |
31 | 30 | */ |
Index: trunk/phase3/includes/WikiPage.php |
— | — | @@ -1275,7 +1275,7 @@ |
1276 | 1276 | |
1277 | 1277 | # Do updates right now unless deferral was requested |
1278 | 1278 | if ( !( $flags & EDIT_DEFER_UPDATES ) ) { |
1279 | | - wfDoUpdates(); |
| 1279 | + DeferredUpdates::doUpdates(); |
1280 | 1280 | } |
1281 | 1281 | |
1282 | 1282 | // Return the new revision (or null) to the caller |
— | — | @@ -1604,7 +1604,7 @@ |
1605 | 1605 | public function doDeleteArticle( |
1606 | 1606 | $reason, $suppress = false, $id = 0, $commit = true, &$error = '', User $user = null |
1607 | 1607 | ) { |
1608 | | - global $wgDeferredUpdateList, $wgUseTrackbacks, $wgEnableInterwikiTemplatesTracking, $wgGlobalDatabase, $wgUser; |
| 1608 | + global $wgUseTrackbacks, $wgEnableInterwikiTemplatesTracking, $wgGlobalDatabase, $wgUser; |
1609 | 1609 | $user = is_null( $user ) ? $wgUser : $user; |
1610 | 1610 | |
1611 | 1611 | wfDebug( __METHOD__ . "\n" ); |
— | — | @@ -1620,8 +1620,9 @@ |
1621 | 1621 | return false; |
1622 | 1622 | } |
1623 | 1623 | |
1624 | | - $u = new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ); |
1625 | | - array_push( $wgDeferredUpdateList, $u ); |
| 1624 | + DeferredUpdates::addUpdate( |
| 1625 | + new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) |
| 1626 | + ); |
1626 | 1627 | |
1627 | 1628 | // Bitfields to further suppress the content |
1628 | 1629 | if ( $suppress ) { |
— | — | @@ -1939,15 +1940,15 @@ |
1940 | 1941 | * @param $user User The relevant user |
1941 | 1942 | */ |
1942 | 1943 | public function doViewUpdates( User $user ) { |
1943 | | - global $wgDeferredUpdateList, $wgDisableCounters; |
| 1944 | + global $wgDisableCounters; |
1944 | 1945 | if ( wfReadOnly() ) { |
1945 | 1946 | return; |
1946 | 1947 | } |
1947 | 1948 | |
1948 | 1949 | # Don't update page view counters on views from bot users (bug 14044) |
1949 | 1950 | if ( !$wgDisableCounters && !$user->isAllowed( 'bot' ) && $this->getId() ) { |
1950 | | - $wgDeferredUpdateList[] = new ViewCountUpdate( $this->getId() ); |
1951 | | - $wgDeferredUpdateList[] = new SiteStatsUpdate( 1, 0, 0 ); |
| 1951 | + DeferredUpdates::addUpdate( new ViewCountUpdate( $this->getId() ) ); |
| 1952 | + DeferredUpdates::addUpdate( new SiteStatsUpdate( 1, 0, 0 ) ); |
1952 | 1953 | } |
1953 | 1954 | |
1954 | 1955 | # Update newtalk / watchlist notification status |
— | — | @@ -2004,7 +2005,7 @@ |
2005 | 2006 | * - null: don't change the article count |
2006 | 2007 | */ |
2007 | 2008 | public function doEditUpdates( Revision $revision, User $user, array $options = array() ) { |
2008 | | - global $wgDeferredUpdateList, $wgEnableParserCache; |
| 2009 | + global $wgEnableParserCache; |
2009 | 2010 | |
2010 | 2011 | wfProfileIn( __METHOD__ ); |
2011 | 2012 | |
— | — | @@ -2072,8 +2073,8 @@ |
2073 | 2074 | $total = 0; |
2074 | 2075 | } |
2075 | 2076 | |
2076 | | - $wgDeferredUpdateList[] = new SiteStatsUpdate( 0, 1, $good, $total ); |
2077 | | - $wgDeferredUpdateList[] = new SearchUpdate( $id, $title, $text ); |
| 2077 | + DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, $good, $total ) ); |
| 2078 | + DeferredUpdates::addUpdate( new SearchUpdate( $id, $title, $text ) ); |
2078 | 2079 | |
2079 | 2080 | # If this is another user's talk page, update newtalk. |
2080 | 2081 | # Don't do this if $options['changed'] = false (null-edits) nor if |
— | — | @@ -2221,8 +2222,6 @@ |
2222 | 2223 | * @param $title Title object |
2223 | 2224 | */ |
2224 | 2225 | public static function onArticleCreate( $title ) { |
2225 | | - global $wgDeferredUpdateList; |
2226 | | - |
2227 | 2226 | # Update existence markers on article/talk tabs... |
2228 | 2227 | if ( $title->isTalkPage() ) { |
2229 | 2228 | $other = $title->getSubjectPage(); |
— | — | @@ -2238,7 +2237,7 @@ |
2239 | 2238 | $title->deleteTitleProtection(); |
2240 | 2239 | |
2241 | 2240 | # Invalidate caches of distant articles which transclude this page |
2242 | | - $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'globaltemplatelinks' ); |
| 2241 | + DeferredUpdates::addHTMLCacheUpdate( $title, 'globaltemplatelinks' ); |
2243 | 2242 | } |
2244 | 2243 | |
2245 | 2244 | /** |
— | — | @@ -2247,8 +2246,6 @@ |
2248 | 2247 | * @param $title Title |
2249 | 2248 | */ |
2250 | 2249 | public static function onArticleDelete( $title ) { |
2251 | | - global $wgDeferredUpdateList; |
2252 | | - |
2253 | 2250 | # Update existence markers on article/talk tabs... |
2254 | 2251 | if ( $title->isTalkPage() ) { |
2255 | 2252 | $other = $title->getSubjectPage(); |
— | — | @@ -2286,7 +2283,7 @@ |
2287 | 2284 | RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $title ); |
2288 | 2285 | |
2289 | 2286 | # Invalidate caches of distant articles which transclude this page |
2290 | | - $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'globaltemplatelinks' ); |
| 2287 | + DeferredUpdates::addHTMLCacheUpdate( $title, 'globaltemplatelinks' ); |
2291 | 2288 | } |
2292 | 2289 | |
2293 | 2290 | /** |
— | — | @@ -2296,16 +2293,14 @@ |
2297 | 2294 | * @todo: verify that $title is always a Title object (and never false or null), add Title hint to parameter $title |
2298 | 2295 | */ |
2299 | 2296 | public static function onArticleEdit( $title ) { |
2300 | | - global $wgDeferredUpdateList; |
2301 | | - |
2302 | 2297 | // Invalidate caches of articles which include this page |
2303 | | - $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'templatelinks' ); |
| 2298 | + DeferredUpdates::addHTMLCacheUpdate( $title, 'templatelinks' ); |
2304 | 2299 | |
2305 | 2300 | // Invalidate caches of distant articles which transclude this page |
2306 | | - $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'globaltemplatelinks' ); |
| 2301 | + DeferredUpdates::addHTMLCacheUpdate( $title, 'globaltemplatelinks' ); |
2307 | 2302 | |
2308 | 2303 | // Invalidate the caches of all pages which redirect here |
2309 | | - $wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'redirect' ); |
| 2304 | + DeferredUpdates::addHTMLCacheUpdate( $title, 'redirect' ); |
2310 | 2305 | |
2311 | 2306 | # Purge squid for this page only |
2312 | 2307 | $title->purgeSquid(); |
Index: trunk/phase3/includes/ViewCountUpdate.php |
— | — | @@ -27,7 +27,7 @@ |
28 | 28 | * 'page_counter' field or use the 'hitcounter' table and then collect the data |
29 | 29 | * from that table to update the 'page_counter' field in a batch operation. |
30 | 30 | */ |
31 | | -class ViewCountUpdate { |
| 31 | +class ViewCountUpdate implements DeferrableUpdate { |
32 | 32 | protected $id; |
33 | 33 | |
34 | 34 | /** |