WatchedItemStore: Update process cache when adding items
authorTimo Tijhof <krinklemail@gmail.com>
Wed, 2 Nov 2016 00:00:07 +0000 (00:00 +0000)
committerTimo Tijhof <krinklemail@gmail.com>
Wed, 2 Nov 2016 00:13:35 +0000 (00:13 +0000)
This way, when submitting POST to action=watch, the response will
not show "Unwatched" in the navigation 'content action' tabs.

This was previously the case on any wiki installation that has
more than 1 database as the skin would call User::isWatched(),
which would query stale data from a slave.

This doesn't yet account for the reverse use case (removing from
watchlist). That's to be addressed in a later commit.

Bug: T28292
Change-Id: Ie4b69c985815a77b70692db0c4dbf52e1a6a018d

includes/WatchedItemStore.php

index 6c47cae..cc4779e 100644 (file)
@@ -167,7 +167,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @param User $user
         * @param LinkTarget $target
         *
-        * @return WatchedItem|null
+        * @return WatchedItem|false
         */
        private function getCached( User $user, LinkTarget $target ) {
                return $this->cache->get( $this->getCacheKey( $user, $target ) );
@@ -495,7 +495,7 @@ class WatchedItemStore implements StatsdAwareInterface {
 
                $watchedItems = [];
                foreach ( $res as $row ) {
-                       // todo these could all be cached at some point?
+                       // @todo: Should we add these to the process cache?
                        $watchedItems[] = new WatchedItem(
                                $user,
                                new TitleValue( (int)$row->wl_namespace, $row->wl_title ),
@@ -602,6 +602,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                }
 
                $rows = [];
+               $items = [];
                foreach ( $targets as $target ) {
                        $rows[] = [
                                'wl_user' => $user->getId(),
@@ -609,6 +610,11 @@ class WatchedItemStore implements StatsdAwareInterface {
                                'wl_title' => $target->getDBkey(),
                                'wl_notificationtimestamp' => null,
                        ];
+                       $items[] = new WatchedItem(
+                               $user,
+                               $target,
+                               null
+                       );
                        $this->uncache( $user, $target );
                }
 
@@ -618,6 +624,12 @@ class WatchedItemStore implements StatsdAwareInterface {
                        // if there's already an entry for this page
                        $dbw->insert( 'watchlist', $toInsert, __METHOD__, 'IGNORE' );
                }
+               // Update process cache to ensure skin doesn't claim that the current
+               // page is unwatched in the response of action=watch itself (T28292).
+               // This would otherwise be re-queried from a slave by isWatched().
+               foreach ( $items as $item ) {
+                       $this->cache( $item );
+               }
 
                return true;
        }