[MCR] Don't require $title to be passed to Revision::newFromId
authoraddshore <addshorewiki@gmail.com>
Fri, 22 Dec 2017 17:32:54 +0000 (17:32 +0000)
committeraddshore <addshorewiki@gmail.com>
Sat, 23 Dec 2017 10:54:17 +0000 (10:54 +0000)
If the title is not passed in as a param (already known) then select
it in Revision::newFromId instead of waiting for it to be selected
further down the tree.
This means that we can use the same Title object to pass into the
RevisionRecord as well as our legacy Revision object.

The selection chooses either a slave or master depending on
recent writes.

This logic used to be in Revision::getTitle and also in
Revision::newFromConds which was called by newFromId

Bug: T183505
Change-Id: I9cf4ce2c3c86d6bf979a3c88eb423b942b9a1ba4

includes/Revision.php

index ed0646a..0b58324 100644 (file)
@@ -90,10 +90,52 @@ class Revision implements IDBAccessObject {
         *
         * @param int $id
         * @param int $flags (optional)
-        * @param Title $title (optional)
+        * @param Title $title (optional) If known you can pass the Title in here.
+        *  Passing no Title may result in another DB query if there are recent writes.
         * @return Revision|null
         */
        public static function newFromId( $id, $flags = 0, Title $title = null ) {
+               /**
+                * MCR RevisionStore Compat
+                *
+                * If the title is not passed in as a param (already known) then select it here.
+                *
+                * Do the selection with MASTER if $flags includes READ_LATEST or recent changes
+                * have happened on our load balancer.
+                *
+                * If we select the title here and pass it down it will results in fewer queries
+                * further down the stack.
+                */
+               if ( !$title ) {
+                       if (
+                               $flags & self::READ_LATEST ||
+                               wfGetLB()->hasOrMadeRecentMasterChanges()
+                       ) {
+                               $dbr = wfGetDB( DB_MASTER );
+                       } else {
+                               $dbr = wfGetDB( DB_REPLICA );
+                       }
+                       $row = $dbr->selectRow(
+                               [ 'revision', 'page' ],
+                               [
+                                       'page_namespace',
+                                       'page_title',
+                                       'page_id',
+                                       'page_latest',
+                                       'page_is_redirect',
+                                       'page_len',
+                               ],
+                               [ 'rev_id' => $id ],
+                               __METHOD__,
+                               [],
+                               [ 'page' => [ 'JOIN', 'page_id=rev_page' ] ]
+                       );
+                       if ( $row ) {
+                               $title = Title::newFromRow( $row );
+                       }
+                       wfGetLB()->reuseConnection( $dbr );
+               }
+
                $rec = self::getRevisionStore()->getRevisionById( $id, $flags, $title );
                return $rec === null ? null : new Revision( $rec, $flags, $title );
        }