r114044 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r114043‎ | r114044 | r114045 >
Date:00:51, 17 March 2012
Author:jeroendedauw
Status:deferred
Tags:
Comment:
playing with some stuff to make partial caching of special pages easier
Modified paths:
  • /trunk/extensions/EducationProgram/specials/SpecialCachedPage.php (modified) (history)
  • /trunk/extensions/EducationProgram/specials/SpecialEPPage.php (modified) (history)
  • /trunk/extensions/EducationProgram/specials/SpecialStudentActivity.php (modified) (history)

Diff [purge]

Index: trunk/extensions/EducationProgram/specials/SpecialEPPage.php
@@ -12,7 +12,7 @@
1313 * @licence GNU GPL v3 or later
1414 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1515 */
16 -abstract class SpecialEPPage extends SpecialPage {
 16+abstract class SpecialEPPage extends SpecialCachedPage {
1717
1818 /**
1919 * The subpage, ie the part after Special:PageName/
@@ -54,6 +54,8 @@
5555 * @return boolean
5656 */
5757 public function execute( $subPage ) {
 58+ parent::execute( $subPage );
 59+
5860 $subPage = is_null( $subPage ) ? '' : $subPage;
5961 $this->subPage = trim( str_replace( '_', ' ', $subPage ) );
6062
Index: trunk/extensions/EducationProgram/specials/SpecialStudentActivity.php
@@ -20,6 +20,7 @@
2121 */
2222 public function __construct() {
2323 parent::__construct( 'StudentActivity' );
 24+ $this->cacheExpiry = 600;
2425 }
2526
2627 /**
@@ -30,34 +31,40 @@
3132 * @param string $subPage
3233 */
3334 public function execute( $subPage ) {
34 - parent::execute( $subPage );
 35+ //parent::execute( $subPage );
3536
36 - $cache = wfGetCache( CACHE_ANYTHING );
37 - $cacheKey = wfMemcKey( get_class( $this ), $this->getLanguage()->getCode() );
38 - $cachedHTML = $cache->get( $cacheKey );
 37+ if ( !is_null( $this->cacheExpiry ) ) {
 38+ $cache = wfGetCache( CACHE_ANYTHING );
 39+ $cacheKey = $this->getCacheKey();
 40+ $cachedHTML = $cache->get( $cacheKey );
3941
40 - $out = $this->getOutput();
 42+ $out = $this->getOutput();
4143
42 - if ( $this->getRequest()->getText( 'action' ) !== 'purge' && is_string( $cachedHTML ) ) {
43 - $html = $cachedHTML;
44 - }
45 - else {
46 - $conds = array( 'last_active > ' . wfGetDB( DB_SLAVE )->addQuotes(
47 - wfTimestamp( TS_MW, time() - ( EPSettings::get( 'recentActivityLimit' ) ) )
48 - ) );
 44+ if ( $this->getRequest()->getText( 'action' ) !== 'purge' && is_string( $cachedHTML ) ) {
 45+ $html = $cachedHTML;
 46+ }
 47+ else {
 48+ $this->displayCachedContent();
4949
50 - $this->displayStudentMeter( $conds );
51 - $this->displayPager( $conds );
 50+ $html = $out->getHTML();
 51+ $cache->set( $cacheKey, $html, $this->cacheExpiry );
 52+ }
5253
53 - $html = $out->getHTML();
54 - $cache->set( $cacheKey, $html, 3600 );
 54+ $out->clearHTML();
 55+
 56+ $this->displayBeforeCached();
 57+ $out->addHTML( $html );
 58+ $this->displayAfterCached();
5559 }
 60+ }
5661
57 - $out->clearHTML();
 62+ protected function displayCachedContent() {
 63+ $conds = array( 'last_active > ' . wfGetDB( DB_SLAVE )->addQuotes(
 64+ wfTimestamp( TS_MW, time() - ( EPSettings::get( 'recentActivityLimit' ) ) )
 65+ ) );
5866
59 - $this->displayNavigation();
60 -
61 - $out->addHTML( $html );
 67+ $this->displayStudentMeter( $conds );
 68+ $this->displayPager( $conds );
6269 }
6370
6471 public function displayPager( array $conds ) {
Index: trunk/extensions/EducationProgram/specials/SpecialCachedPage.php
@@ -1,5 +1,142 @@
22 <?php
33
 4+class CachedOutput {
 5+
 6+ /**
 7+ * The time to live for the cache, in seconds or a unix timestamp indicating the point of expiry.
 8+ *
 9+ * @since 0.1
 10+ * @var integer
 11+ */
 12+ protected $cacheExpiry = 3600;
 13+
 14+ protected $cachedChunks;
 15+
 16+ protected $hasCached = null;
 17+
 18+ protected $out;
 19+
 20+ public function __construct( OutputPage $out ) {
 21+ $this->out = $out;
 22+ }
 23+
 24+ public function invalidateCache() {
 25+ $this->hasCached = false;
 26+ }
 27+
 28+ /**
 29+ * Initializes the caching.
 30+ * Should be called ONCE before any of the caching functionality is used,
 31+ * only when $this->hasCached is null.
 32+ *
 33+ * @since 0.1
 34+ */
 35+ protected function initCaching() {
 36+ $cachedChunks = wfGetCache( CACHE_ANYTHING )->get( $this->getCacheKey() );
 37+
 38+ $this->hasCached = is_array( $cachedChunks );
 39+ $this->cachedChunks = $this->hasCached ? $cachedChunks : array();
 40+ }
 41+
 42+ /**
 43+ * Add some HTML to be cached.
 44+ * This is done by providing a callback function that should
 45+ * return the HTML to be added. It will only be called if the
 46+ * item is not in the cache yet or when the cache has been invalidated.
 47+ *
 48+ * @since 0.1
 49+ *
 50+ * @param {function} $callback
 51+ * @param array $args
 52+ * @param string|null $key
 53+ */
 54+ public function addCachedHTML( $callback, $args = array(), $key = null ) {
 55+ if ( is_null( $this->hasCached ) ) {
 56+ $this->initCaching();
 57+ }
 58+
 59+ if ( $this->hasCached ) {
 60+ $html = '';
 61+
 62+ if ( is_null( $key ) ) {
 63+ $itemKey = array_flip( array_slice( $this->cachedChunks, 0, 1 ) );
 64+ $itemKey = array_shift( $itemKey );
 65+
 66+ if ( is_integer( $itemKey ) ) {
 67+ wfWarn( "Attempted to get item with non-numeric key while the next item in the queue has a key ($itemKey) in " . __METHOD__ );
 68+ }
 69+ elseif ( is_null( $itemKey ) ) {
 70+ wfWarn( "Attempted to get an item while the queue is empty in " . __METHOD__ );
 71+ }
 72+ else {
 73+ $html = array_shift( $key );
 74+ }
 75+ }
 76+ else {
 77+ if ( array_key_exists( $key, $this->cachedChunks ) ) {
 78+ $html = $this->cachedChunks[$key];
 79+ unset( $this->cachedChunks[$key] );
 80+ }
 81+ else {
 82+ wfWarn( "There is no item with key '$key' in this->cachedChunks in " . __METHOD__ );
 83+ }
 84+ }
 85+ }
 86+ else {
 87+ $html = call_user_func_array( $callback, $args );
 88+
 89+ if ( is_null( $key ) ) {
 90+ $this->cachedChunks[] = $html;
 91+ }
 92+ else {
 93+ $this->cachedChunks[$key] = $html;
 94+ }
 95+ }
 96+
 97+ $this->addHTML( $html );
 98+ }
 99+
 100+ public function addHTML( $html ) {
 101+ $this->out->addHTML( $html );
 102+ }
 103+
 104+ /**
 105+ * Saves the HTML to the cache in case it got recomputed.
 106+ * Should be called after the last time anything is added via addCachedHTML.
 107+ *
 108+ * @since 0.1
 109+ */
 110+ public function saveCache() {
 111+ if ( !$this->hasCached && !empty( $this->cachedChunks ) ) {
 112+ wfGetCache( CACHE_ANYTHING )->set( $this->getCacheKey(), $this->cachedChunks, $this->cacheExpiry );
 113+ }
 114+ }
 115+
 116+ /**
 117+ * Sets the time to live for the cache, in seconds or a unix timestamp indicating the point of expiry..
 118+ *
 119+ * @since 0.1
 120+ *
 121+ * @param integer $cacheExpiry
 122+ */
 123+ protected function setExpirey( $cacheExpiry ) {
 124+ $this->cacheExpiry = $cacheExpiry;
 125+ }
 126+
 127+ /**
 128+ * Returns the cache key to use to cache this page's HTML output.
 129+ * Is constructed from the special page name and language code.
 130+ *
 131+ * @since 0.1
 132+ *
 133+ * @return string
 134+ */
 135+ protected function getCacheKey() {
 136+ return wfMemcKey( $this->mName, $this->getLanguage()->getCode() );
 137+ }
 138+
 139+}
 140+
4141 /**
5142 * Abstract special page class with scaffolding for caching the HTML output.
6143 *
@@ -14,13 +151,15 @@
15152 abstract class SpecialCachedPage extends SpecialPage {
16153
17154 /**
18 - * The time to live for the cache, in seconds.
 155+ * The time to live for the cache, in seconds or a unix timestamp indicating the point of expiry.
19156 *
20157 * @since 0.1
21 - * @var integer
 158+ * @var integer|null
22159 */
23 - protected $cacheExpiry = 3600;
 160+ protected $cacheExpiry = null;
24161
 162+ protected $cachedOutput = null;
 163+
25164 /**
26165 * Main method.
27166 *
@@ -29,33 +168,35 @@
30169 * @param string $subPage
31170 */
32171 public function execute( $subPage ) {
33 - parent::execute( $subPage );
 172+ //parent::execute( $subPage );
34173
35 - $cache = wfGetCache( CACHE_ANYTHING );
36 - $cacheKey = $this->getCacheKey();
37 - $cachedHTML = $cache->get( $cacheKey );
 174+ if ( !is_null( $this->cacheExpiry ) ) {
 175+ $cache = wfGetCache( CACHE_ANYTHING );
 176+ $cacheKey = $this->getCacheKey();
 177+ $cachedHTML = $cache->get( $cacheKey );
38178
39 - $out = $this->getOutput();
 179+ $out = $this->getOutput();
40180
41 - if ( $this->getRequest()->getText( 'action' ) !== 'purge' && is_string( $cachedHTML ) ) {
42 - $html = $cachedHTML;
43 - }
44 - else {
45 - $this->displayCachedContent();
 181+ if ( $this->getRequest()->getText( 'action' ) !== 'purge' && is_string( $cachedHTML ) ) {
 182+ $html = $cachedHTML;
 183+ }
 184+ else {
 185+ $this->displayCachedContent();
46186
47 - $html = $out->getHTML();
48 - $cache->set( $cacheKey, $html, $this->cacheExpiry );
49 - }
 187+ $html = $out->getHTML();
 188+ $cache->set( $cacheKey, $html, $this->cacheExpiry );
 189+ }
50190
51 - $out->clearHTML();
 191+ $out->clearHTML();
52192
53 - $this->displayBeforeCached();
54 - $out->addHTML( $html );
55 - $this->displayAfterCached();
 193+ $this->displayBeforeCached();
 194+ $out->addHTML( $html );
 195+ $this->displayAfterCached();
 196+ }
56197 }
57198
58199 /**
59 - * Sets the time to live for the cache, in seconds.
 200+ * Sets the time to live for the cache, in seconds or a unix timestamp indicating the point of expiry..
60201 *
61202 * @since 0.1
62203 *

Follow-up revisions

RevisionCommit summaryAuthorDate
r114045Follow up to r114044; decided upon an approach for the caching stuff and got ...jeroendedauw01:23, 17 March 2012

Status & tagging log