74 $rcMaxAge = $services->getMainConfig()->get(
76 $updateRowsPerQuery = $services->getMainConfig()->get(
78 $dbProvider = $services->getConnectionProvider();
79 $dbw = $dbProvider->getPrimaryDatabase();
80 $lockKey = $dbw->getDomainID() .
':recentchanges-prune';
81 if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
85 $ticket = $dbProvider->getEmptyTransactionTicket( __METHOD__ );
86 $hookContainer = $services->getHookContainer();
87 $hookRunner =
new HookRunner( $hookContainer );
88 $cutoff = $dbw->timestamp( ConvertibleTimestamp::time() - $rcMaxAge );
89 $hasLegacyHook = $hookContainer->isRegistered(
'RecentChangesPurgeRows' );
90 if ( $hasLegacyHook ) {
91 $query = $dbw->newSelectQueryBuilder()
93 ->where( $dbw->expr(
'rc_timestamp',
'<', $cutoff ) )
94 ->limit( $updateRowsPerQuery )
95 ->caller( __METHOD__ );
97 $query = $dbw->newSelectQueryBuilder()
99 ->from(
'recentchanges' )
100 ->where( $dbw->expr(
'rc_timestamp',
'<', $cutoff ) )
101 ->limit( $updateRowsPerQuery )
102 ->caller( __METHOD__ );
105 $hookRunner->onRecentChangesPurgeQuery( $query, $callbacks );
107 $res = $query->fetchResultSet();
109 if ( $res->numRows() ) {
111 foreach ( $res as $row ) {
112 $rcIds[] = $row->rc_id;
113 if ( $hasLegacyHook ) {
118 $dbw->newDeleteQueryBuilder()
119 ->deleteFrom(
'recentchanges' )
120 ->where( [
'rc_id' => $rcIds ] )
121 ->caller( __METHOD__ )->execute();
123 foreach ( $callbacks as $callback ) {
126 if ( $hasLegacyHook ) {
127 $hookRunner->onRecentChangesPurgeRows( $rows );
130 if ( !$dbProvider->commitAndWaitForReplication(
131 __METHOD__, $ticket, [
'timeout' => 3 ]
139 $dbw->unlock( $lockKey, __METHOD__ );
144 $activeUserDays = $services->getMainConfig()->get(
148 $days = $activeUserDays;
150 $window = $activeUserDays * 86400;
152 $rcLookup = $services->getRecentChangeLookup();
153 $dbProvider = $services->getConnectionProvider();
154 $dbw = $dbProvider->getPrimaryDatabase();
155 $ticket = $dbProvider->getEmptyTransactionTicket( __METHOD__ );
157 $lockKey = $dbw->getDomainID() .
'-activeusers';
158 if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
165 $dbw->setSessionOptions( [
'connTimeout' => 900 ] );
169 $cTime = $dbw->newSelectQueryBuilder()
170 ->select(
'qci_timestamp' )
171 ->from(
'querycache_info' )
172 ->where( [
'qci_type' =>
'activeusers' ] )
173 ->caller( __METHOD__ )->fetchField();
174 $cTimeUnix = $cTime ? (int)
wfTimestamp( TS::UNIX, $cTime ) : 1;
179 $sTimestamp = max( $cTimeUnix, $nowUnix - $days * 86400 );
180 $eTimestamp = min( $sTimestamp + $window, $nowUnix );
183 $res = $dbw->newSelectQueryBuilder()
184 ->select( [
'actor_name',
'lastedittime' =>
'MAX(rc_timestamp)' ] )
185 ->from(
'recentchanges' )
186 ->join(
'actor',
null,
'actor_id=rc_actor' )
188 $dbw->expr(
'actor_user',
'!=',
null ),
189 $dbw->expr(
'rc_source',
'=', $rcLookup->getPrimarySources() ),
190 $dbw->expr(
'rc_log_type',
'=',
null )->or(
'rc_log_type',
'!=',
'newusers' ),
191 $dbw->expr(
'rc_timestamp',
'>=', $dbw->timestamp( $sTimestamp ) ),
192 $dbw->expr(
'rc_timestamp',
'<=', $dbw->timestamp( $eTimestamp ) ),
194 ->groupBy(
'actor_name' )
196 ->caller( __METHOD__ )->fetchResultSet();
199 foreach ( $res as $row ) {
200 $names[$row->actor_name] = $row->lastedittime;
204 if ( count( $names ) ) {
205 $res = $dbw->newSelectQueryBuilder()
206 ->select( [
'user_name' =>
'qcc_title' ] )
207 ->from(
'querycachetwo' )
209 'qcc_type' =>
'activeusers',
211 'qcc_title' => array_map(
'strval', array_keys( $names ) ),
212 $dbw->expr(
'qcc_value',
'>=', $nowUnix - $days * 86400 ),
214 ->caller( __METHOD__ )->fetchResultSet();
217 foreach ( $res as $row ) {
218 unset( $names[$row->user_name] );
223 if ( count( $names ) ) {
225 foreach ( $names as $name => $lastEditTime ) {
227 'qcc_type' =>
'activeusers',
229 'qcc_title' => $name,
230 'qcc_value' => (int)
wfTimestamp( TS::UNIX, $lastEditTime ),
231 'qcc_namespacetwo' => 0,
235 foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
236 $dbw->newInsertQueryBuilder()
237 ->insertInto(
'querycachetwo' )
239 ->caller( __METHOD__ )->execute();
240 $dbProvider->commitAndWaitForReplication( __METHOD__, $ticket );
246 $asOfTimestamp = min( $eTimestamp, (
int)$dbw->trxTimestamp() );
249 $dbw->newReplaceQueryBuilder()
250 ->replaceInto(
'querycache_info' )
252 'qci_type' =>
'activeusers',
253 'qci_timestamp' => $dbw->timestamp( $asOfTimestamp ),
255 ->uniqueIndexFields( [
'qci_type' ] )
256 ->caller( __METHOD__ )->execute();
259 $dbw->newDeleteQueryBuilder()
260 ->deleteFrom(
'querycachetwo' )
262 'qcc_type' =>
'activeusers',
263 $dbw->expr(
'qcc_value',
'<', $nowUnix - $days * 86400 )
265 ->caller( __METHOD__ )->execute();
268 SiteStatsUpdate::cacheUpdate( $dbw );
271 $dbw->unlock( $lockKey, __METHOD__ );