jenkins-bot has submitted this change and it was merged.

Change subject: MobilePage: Avoid uncached query for Last modified timestamp
......................................................................


MobilePage: Avoid uncached query for Last modified timestamp

MediaWiki's SkinTemplate contains a variable "lastmod" for this, set
by Skin::lastModified() via OutputPage::getRevisionTimestamp()
which is filled in from ParserOutput cache in Article.php.

According to Xenon, SkinMinerva::getHistoryLink spends most of its
time doing at least 3 database queries, even for simple page views.

SkinMinerva::getHistoryLink:
- Message::parse
- MobilePage::__construct
  1. Database::select (via PageImages::getPageImage)
- MobilePage::getLatestTimestamp
  2. Database::select (via Revision::getTimestampFromId)
- MobilePage::getLatestEdit
  3. Database::select (via Revision::newFromId)
  4. Database::select (via MobilePage::getLatestTimestamp)

Changes:
* Avoid #2 by calling OutputPage::getRevisionTimestamp instead, which has
  the same value pre-populated from ParserOutput cache.
* Avoid #3 by using Revision::newKnownCurrent, which uses Memcached.
* Avoid #4 in some cases by making MobilePage remember the result of #2
  in the instance instead of querying the same thing twice.

Also:
* Remove redundant explicit User::load() call. Fields are lazy-loaded.
  It was added in 0a68545711 to avoid master queries, but slave-db has
  been the default in User for a while now (mid-2015; dd42294d2).
* Document the non-obvious difference in timestamp format between
  getLatestEdit and getLatestTimestamp.

Change-Id: Ia135e61604fa8551caac50dca43b5dc9154babd4
---
M includes/models/MobilePage.php
M includes/skins/SkinMinerva.php
2 files changed, 41 insertions(+), 10 deletions(-)

Approvals:
  Gilles: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/models/MobilePage.php b/includes/models/MobilePage.php
index 03e53ac..4f24076 100644
--- a/includes/models/MobilePage.php
+++ b/includes/models/MobilePage.php
@@ -17,6 +17,10 @@
         */
        private $title;
        /**
+        * @var Revision|bool
+        */
+       private $rev;
+       /**
         * @var File Associated page image file (see PageImages extension)
         */
        private $file;
@@ -43,32 +47,56 @@
                }
        }
 
+       private function getRevision() {
+               if ( $this->rev === null ) {
+                       $this->rev = Revision::newKnownCurrent(
+                               wfGetDB( DB_REPLICA ),
+                               $this->title->getArticleID(),
+                               $this->title->getLatestRevID()
+                       );
+               }
+               return $this->rev;
+       }
+
        /**
-        * Retrieve the last time the page content was modified. Do not reflect 
null edits.
-        * @return string timestamp representing last edited time.
+        * Retrieve timestamp when the page content was last modified. Does not 
reflect null edits.
+        * @return string|bool Timestamp (MW format) or false
         */
        public function getLatestTimestamp() {
-               $title = $this->getTitle();
-               return Revision::getTimestampFromId( $title, 
$title->getLatestRevID() );
+               if ( $this->revisionTimestamp === null ) {
+                       $rev = $this->getRevision();
+                       $this->revisionTimestamp = $rev ? $rev->getTimestamp() 
: false;
+               }
+               return $this->revisionTimestamp;
+       }
+
+       /**
+        * Set rev_timestamp of latest edit to this page
+        * @param string Timestamp (MW format)
+        */
+       public function setLatestTimestamp( $timestamp ) {
+               $this->revisionTimestamp = $timestamp;
        }
 
        /**
         * Retrieve the last edit to this page.
-        * @return array defining edit with keys name, timestamp and gender
+        * @return array defining edit with keys:
+        * - string name
+        * - string timestamp (Unix format)
+        * - string gender
         */
        public function getLatestEdit() {
-               $rev = Revision::newFromId( $this->getTitle()->getLatestRevID() 
);
-               $unixTimestamp = wfTimestamp( TS_UNIX, 
$this->getLatestTimestamp() );
+               $rev = $this->getRevision();
                $edit = [
-                       'timestamp' => $unixTimestamp,
+                       'timestamp' => false,
                        'name' => '',
                        'gender' => '',
                ];
                if ( $rev ) {
+                       $edit['timestamp'] = wfTimestamp( TS_UNIX, 
$rev->getTimestamp() );
                        $userId = $rev->getUser();
                        if ( $userId ) {
                                $revUser = User::newFromId( $userId );
-                               $revUser->load( User::READ_NORMAL );
                                $edit['name'] = $revUser->getName();
                                $edit['gender'] = $revUser->getOption( 'gender' 
);
                        }
diff --git a/includes/skins/SkinMinerva.php b/includes/skins/SkinMinerva.php
index 9c4c02d..00f2066 100644
--- a/includes/skins/SkinMinerva.php
+++ b/includes/skins/SkinMinerva.php
@@ -690,8 +690,10 @@
        protected function getHistoryLink( Title $title ) {
                $user = $this->getUser();
                $isMainPage = $title->isMainPage();
+               // Get rev_timestamp of current revision (preloaded by 
MediaWiki core)
+               $timestamp = $this->getOutput()->getRevisionTimestamp();
                $mp = new MobilePage( $this->getTitle(), false );
-               $timestamp = $mp->getLatestTimestamp();
+               $mp->setLatestTimestamp( $timestamp );
                // Main pages tend to include transclusions (see bug 51924)
                if ( $isMainPage ) {
                        $lastModified = $this->msg( 'mobile-frontend-history' 
)->plain();
@@ -704,6 +706,7 @@
                }
                $edit = $mp->getLatestEdit();
                $link = [
+                       // Use $edit['timestamp'] (Unix format) instead of 
$timestamp (MW format)
                        'data-timestamp' => $isMainPage ? '' : 
$edit['timestamp'],
                        'href' => SpecialPage::getTitleFor( 'History', $title 
)->getLocalURL(),
                        'text' => $lastModified,

-- 
To view, visit https://gerrit.wikimedia.org/r/314787
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia135e61604fa8551caac50dca43b5dc9154babd4
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Krinkle <krinklem...@gmail.com>
Gerrit-Reviewer: Aaron Schulz <asch...@wikimedia.org>
Gerrit-Reviewer: Gilles <gdu...@wikimedia.org>
Gerrit-Reviewer: Jdlrobson <jrob...@wikimedia.org>
Gerrit-Reviewer: Krinkle <krinklem...@gmail.com>
Gerrit-Reviewer: Ori.livneh <o...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to