MediaWiki master
ClearUserWatchlistJob.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Watchlist;
4
10
24 public function __construct( array $params ) {
25 parent::__construct( 'clearUserWatchlist', $params );
26
27 $this->removeDuplicates = true;
28 }
29
36 public static function newForUser( UserIdentity $user, $maxWatchlistId ) {
37 return new self( [ 'userId' => $user->getId(), 'maxWatchlistId' => $maxWatchlistId ] );
38 }
39
41 public function run() {
42 $config = MediaWikiServices::getInstance()->getMainConfig();
43 $dbProvider = MediaWikiServices::getInstance()->getConnectionProvider();
44
45 $batchSize = $config->get( MainConfigNames::UpdateRowsPerQuery );
46 $userId = $this->params['userId'];
47 $maxWatchlistId = $this->params['maxWatchlistId'];
48
49 $dbw = $dbProvider->getPrimaryDatabase();
50 $dbr = $dbProvider->getReplicaDatabase();
51 $ticket = $dbProvider->getEmptyTransactionTicket( __METHOD__ );
52
53 // Use a named lock so that jobs for this user see each others' changes
54 $lockKey = "ClearUserWatchlist:$userId"; // per-wiki
55 $scopedLock = MediaWikiServices::getInstance()->getLockManager()->scopedLock( $lockKey );
56 if ( !$scopedLock ) {
57 $this->setLastError( "Could not acquire lock '$lockKey'" );
58 return false;
59 }
60
61 // Optimization: Query the replica instead of the primary.
62 // Therefore, ensure we're caught up with the latest changes first
63 $dbProvider->commitAndWaitForReplication( __METHOD__, $ticket );
64
65 $watchlistIds = $dbr->newSelectQueryBuilder()
66 ->select( 'wl_id' )
67 ->from( 'watchlist' )
68 ->where( [ 'wl_user' => $userId ] )
69 ->andWhere( $dbr->expr( 'wl_id', '<=', $maxWatchlistId ) )
70 ->limit( $batchSize )
71 ->caller( __METHOD__ )->fetchFieldValues();
72 if ( !$watchlistIds ) {
73 return true;
74 }
75
76 $dbw->newDeleteQueryBuilder()
77 ->deleteFrom( 'watchlist' )
78 ->where( [ 'wl_id' => $watchlistIds ] )
79 ->caller( __METHOD__ )->execute();
80
81 if ( $config->get( MainConfigNames::WatchlistExpiry ) ) {
82 $dbw->newDeleteQueryBuilder()
83 ->deleteFrom( 'watchlist_expiry' )
84 ->where( [ 'we_item' => $watchlistIds ] )
85 ->caller( __METHOD__ )->execute();
86 }
87
88 // Commit changes and remove lock before inserting next job.
89 $dbProvider->commitAndWaitForReplication( __METHOD__, $ticket );
90 unset( $scopedLock );
91
92 if ( count( $watchlistIds ) === (int)$batchSize ) {
93 // Until we get less results than the limit, repeat the same job later.
94 MediaWikiServices::getInstance()->getJobQueueGroup()->push( new self( $this->getParams() ) );
95 }
96
97 return true;
98 }
99
101 public function getDeduplicationInfo() {
102 $info = parent::getDeduplicationInfo();
103 // This job never has a namespace or title so we can't use it for deduplication
104 unset( $info['namespace'] );
105 unset( $info['title'] );
106 return $info;
107 }
108
109}
111class_alias( ClearUserWatchlistJob::class, 'ClearUserWatchlistJob' );
Describe and execute a background job.
Definition Job.php:28
array $params
Array of job parameters.
Definition Job.php:33
setLastError( $error)
Definition Job.php:424
getParams()
array Parameters that specify sources, targets, and options for execution
Definition Job.php:143
A class containing constants representing the names of configuration variables.
const UpdateRowsPerQuery
Name constant for the UpdateRowsPerQuery setting, for use with Config::get()
const WatchlistExpiry
Name constant for the WatchlistExpiry setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Job to clear a users watchlist in batches.
getDeduplicationInfo()
Subclasses may need to override this to make duplication detection work.The resulting map conveys eve...
run()
Run the job.If this method returns false or completes exceptionally, the job runner will retry execut...
static newForUser(UserIdentity $user, $maxWatchlistId)
Interface for generic jobs only uses the parameters field and are JSON serializable.
Interface for objects representing user identity.
getId( $wikiId=self::LOCAL)