Follow-up r79518: added getCachedLastEditTime/getCachedLastEditTime methods to WikiPa...
[lhc/web/wiklou.git] / includes / WikiPage.php
index 61bda70..10b4809 100644 (file)
@@ -54,9 +54,15 @@ class WikiPage extends Page {
         * @return WikiPage object of the appropriate type
         */
        public static function factory( Title $title ) {
-               switch( $title->getNamespace() ) {
-                       case NS_MEDIA:
-                               throw new MWException( "NS_MEDIA is a virtual namespace" );
+               $ns = $title->getNamespace();
+
+               if ( $ns == NS_MEDIA ) {
+                       throw new MWException( "NS_MEDIA is a virtual namespace; use NS_FILE." );
+               } elseif ( $ns < 0 ) {
+                       throw new MWException( "Invalid or virtual namespace $ns given." );
+               }
+
+               switch ( $ns ) {
                        case NS_FILE:
                                $page = new WikiFilePage( $title );
                                break;
@@ -76,6 +82,8 @@ class WikiPage extends Page {
         * Always override this for all subclasses (until we use PHP with LSB)
         *
         * @param $id Int article ID to load
+        *
+        * @return WikiPage
         */
        public static function newFromID( $id ) {
                $t = Title::newFromID( $id );
@@ -272,6 +280,8 @@ class WikiPage extends Page {
        /**
         * Return the list of revision fields that should be selected to create
         * a new page.
+        *
+        * @return array
         */
        public static function selectFields() {
                return array(
@@ -336,18 +346,32 @@ class WikiPage extends Page {
         * Set the general counter, title etc data loaded from
         * some source.
         *
-        * @param $data Object|String $res->fetchObject() object or the string "fromdb" to reload
+        * @param $data Object|String One of the following:
+        *              A DB query result object or...
+        *              "fromdb" to get from a slave DB or...
+        *              "fromdbmaster" to get from the master DB
+        * @return void
         */
        public function loadPageData( $data = 'fromdb' ) {
-               if ( $data === 'fromdb' ) {
-                       $dbr = wfGetDB( DB_SLAVE );
-                       $data = $this->pageDataFromTitle( $dbr, $this->mTitle );
+               if ( $data === 'fromdbmaster' ) {
+                       $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
+               } elseif ( $data === 'fromdb' ) { // slave
+                       $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
+                       # Use a "last rev inserted" timestamp key to dimish the issue of slave lag.
+                       # Note that DB also stores the master position in the session and checks it.
+                       $touched = $this->getCachedLastEditTime();
+                       if ( $touched ) { // key set
+                               if ( !$data || $touched > wfTimestamp( TS_MW, $data->page_touched ) ) {
+                                       $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
+                               }
+                       }
                }
 
                $lc = LinkCache::singleton();
 
                if ( $data ) {
-                       $lc->addGoodLinkObj( $data->page_id, $this->mTitle, $data->page_len, $data->page_is_redirect, $data->page_latest );
+                       $lc->addGoodLinkObj( $data->page_id, $this->mTitle,
+                               $data->page_len, $data->page_is_redirect, $data->page_latest );
 
                        $this->mTitle->loadFromRow( $data );
 
@@ -524,7 +548,7 @@ class WikiPage extends Page {
         *      Revision::FOR_THIS_USER    to be displayed to $wgUser
         *      Revision::RAW              get the text regardless of permissions
         * @return String|false The text of the current revision
-        */     
+        */
        public function getText( $audience = Revision::FOR_PUBLIC ) {
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
@@ -799,10 +823,11 @@ class WikiPage extends Page {
                        $conditions['page_latest'] = $lastRevision;
                }
 
+               $now = wfTimestampNow();
                $dbw->update( 'page',
                        array( /* SET */
                                'page_latest'      => $revision->getId(),
-                               'page_touched'     => $dbw->timestamp(),
+                               'page_touched'     => $dbw->timestamp( $now ),
                                'page_is_new'      => ( $lastRevision === 0 ) ? 1 : 0,
                                'page_is_redirect' => $rt !== null ? 1 : 0,
                                'page_len'         => strlen( $text ),
@@ -813,12 +838,34 @@ class WikiPage extends Page {
                $result = $dbw->affectedRows() != 0;
                if ( $result ) {
                        $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
+                       $this->setCachedLastEditTime( $now );
                }
 
                wfProfileOut( __METHOD__ );
                return $result;
        }
 
+       /**
+        * Get the cached timestamp for the last time the page changed
+        * @return string MW timestamp
+        */
+       protected function getCachedLastEditTime() {
+               global $wgMemc;
+               $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) );
+               return $wgMemc->get( $key );
+       }
+
+       /**
+        * Set the cached timestamp for the last time the page changed
+        * @param $timestamp string
+        * @return void
+        */
+       protected function setCachedLastEditTime( $timestamp ) {
+               global $wgMemc;
+               $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) );
+               $wgMemc->set( $key, wfTimestamp( TS_MW, $timestamp ), 60*15 );
+       }
+
        /**
         * Add row to the redirect table if this is a redirect, remove otherwise.
         *
@@ -2060,7 +2107,7 @@ class WikiPage extends Page {
         * @todo This is a shitty interface function. Kill it and replace the
         * other shitty functions like doEditUpdates and such so it's not needed
         * anymore.
-        * @deprecated since 1.19, use doEditUpdates()
+        * @deprecated since 1.18, use doEditUpdates()
         */
        public function createUpdates( $rev ) {
                global $wgUser;
@@ -2509,7 +2556,7 @@ class WikiPage extends Page {
        }
 
        /*
-       * @deprecated since 1.19
+       * @deprecated since 1.18
        */
        public function quickEdit( $text, $comment = '', $minor = 0 ) {
                global $wgUser;
@@ -2517,7 +2564,7 @@ class WikiPage extends Page {
        }
 
        /*
-       * @deprecated since 1.19
+       * @deprecated since 1.18
        */
        public function viewUpdates() {
                global $wgUser;
@@ -2525,7 +2572,7 @@ class WikiPage extends Page {
        }
 
        /*
-       * @deprecated since 1.19
+       * @deprecated since 1.18
        */
        public function useParserCache( $oldid ) {
                global $wgUser;