MediaWiki REL1_34
ClearUserWatchlistJob.php
Go to the documentation of this file.
1<?php
2
5
20 public function __construct( array $params ) {
21 parent::__construct( 'clearUserWatchlist', $params );
22
23 $this->removeDuplicates = true;
24 }
25
32 public static function newForUser( UserIdentity $user, $maxWatchlistId ) {
33 return new self( [ 'userId' => $user->getId(), 'maxWatchlistId' => $maxWatchlistId ] );
34 }
35
36 public function run() {
38 $userId = $this->params['userId'];
39 $maxWatchlistId = $this->params['maxWatchlistId'];
40 $batchSize = $wgUpdateRowsPerQuery;
41
42 $loadBalancer = MediaWikiServices::getInstance()->getDBLoadBalancer();
43 $dbw = $loadBalancer->getConnectionRef( DB_MASTER );
44 $dbr = $loadBalancer->getConnectionRef( DB_REPLICA, [ 'watchlist' ] );
45
46 // Wait before lock to try to reduce time waiting in the lock.
47 if ( !$loadBalancer->waitForMasterPos( $dbr ) ) {
48 $this->setLastError( 'Timed out waiting for replica to catch up before lock' );
49 return false;
50 }
51
52 // Use a named lock so that jobs for this user see each others' changes
53 $lockKey = "{{$dbw->getDomainID()}}:ClearUserWatchlist:$userId"; // per-wiki
54 $scopedLock = $dbw->getScopedLockAndFlush( $lockKey, __METHOD__, 10 );
55 if ( !$scopedLock ) {
56 $this->setLastError( "Could not acquire lock '$lockKey'" );
57 return false;
58 }
59
60 if ( !$loadBalancer->waitForMasterPos( $dbr ) ) {
61 $this->setLastError( 'Timed out waiting for replica to catch up within lock' );
62 return false;
63 }
64
65 // Clear any stale REPEATABLE-READ snapshot
66 $dbr->flushSnapshot( __METHOD__ );
67
68 $watchlistIds = $dbr->selectFieldValues(
69 'watchlist',
70 'wl_id',
71 [
72 'wl_user' => $userId,
73 'wl_id <= ' . $maxWatchlistId
74 ],
75 __METHOD__,
76 [
77 'ORDER BY' => 'wl_id ASC',
78 'LIMIT' => $batchSize,
79 ]
80 );
81
82 if ( count( $watchlistIds ) == 0 ) {
83 return true;
84 }
85
86 $dbw->delete( 'watchlist', [ 'wl_id' => $watchlistIds ], __METHOD__ );
87
88 // Commit changes and remove lock before inserting next job.
89 $lbf = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
90 $lbf->commitMasterChanges( __METHOD__ );
91 unset( $scopedLock );
92
93 if ( count( $watchlistIds ) === (int)$batchSize ) {
94 // Until we get less results than the limit, recursively push
95 // the same job again.
96 JobQueueGroup::singleton()->push( new self( $this->getParams() ) );
97 }
98
99 return true;
100 }
101
102 public function getDeduplicationInfo() {
103 $info = parent::getDeduplicationInfo();
104 // This job never has a namespace or title so we can't use it for deduplication
105 unset( $info['namespace'] );
106 unset( $info['title'] );
107 return $info;
108 }
109
110}
$wgUpdateRowsPerQuery
Number of rows to update per query.
Job to clear a users watchlist in batches.
static newForUser(UserIdentity $user, $maxWatchlistId)
getDeduplicationInfo()
Subclasses may need to override this to make duplication detection work.
Class to both describe a background job and handle jobs.
Definition Job.php:30
getParams()
Definition Job.php:175
setLastError( $error)
Definition Job.php:418
array $params
Array of job parameters.
Definition Job.php:35
MediaWikiServices is the service locator for the application scope of MediaWiki.
Interface for generic jobs only uses the parameters field and are JSON serializable.
Interface for objects representing user identity.
const DB_REPLICA
Definition defines.php:25
const DB_MASTER
Definition defines.php:26