MediaWiki fundraising/REL1_35
SiteStatsUpdate.php
Go to the documentation of this file.
1<?php
21use Wikimedia\Assert\Assert;
23
29 protected $edits = 0;
31 protected $pages = 0;
33 protected $articles = 0;
35 protected $users = 0;
37 protected $images = 0;
38
40 private const COUNTERS = [
41 'ss_total_edits' => 'edits',
42 'ss_total_pages' => 'pages',
43 'ss_good_articles' => 'articles',
44 'ss_users' => 'users',
45 'ss_images' => 'images'
46 ];
47
48 // @todo deprecate this constructor
49 public function __construct( $views, $edits, $good, $pages = 0, $users = 0 ) {
50 $this->edits = $edits;
51 $this->articles = $good;
52 $this->pages = $pages;
53 $this->users = $users;
54 }
55
56 public function merge( MergeableUpdate $update ) {
58 Assert::parameterType( __CLASS__, $update, '$update' );
59 '@phan-var SiteStatsUpdate $update';
60
61 foreach ( self::COUNTERS as $field ) {
62 $this->$field += $update->$field;
63 }
64 }
65
71 public static function factory( array $deltas ) {
72 $update = new self( 0, 0, 0 );
73
74 foreach ( $deltas as $name => $unused ) {
75 if ( !in_array( $name, self::COUNTERS ) ) { // T187585
76 throw new UnexpectedValueException( __METHOD__ . ": no field called '$name'" );
77 }
78 }
79
80 foreach ( self::COUNTERS as $field ) {
81 $update->$field = $deltas[$field] ?? 0;
82 }
83
84 return $update;
85 }
86
87 public function doUpdate() {
88 $services = MediaWikiServices::getInstance();
89 $stats = $services->getStatsdDataFactory();
90
91 $deltaByType = [];
92 foreach ( self::COUNTERS as $type ) {
93 $delta = $this->$type;
94 if ( $delta !== 0 ) {
95 $stats->updateCount( "site.$type", $delta );
96 }
97 $deltaByType[$type] = $delta;
98 }
99
100 ( new AutoCommitUpdate(
101 $services->getDBLoadBalancer()->getConnectionRef( DB_MASTER ),
102 __METHOD__,
103 function ( IDatabase $dbw, $fname ) use ( $deltaByType ) {
104 $set = [];
105 foreach ( self::COUNTERS as $field => $type ) {
106 $delta = (int)$deltaByType[$type];
107 if ( $delta > 0 ) {
108 $set[] = "$field=" . $dbw->buildGreatest(
109 [ $field => $dbw->addIdentifierQuotes( $field ) . '+' . abs( $delta ) ],
110 0
111 );
112 } elseif ( $delta < 0 ) {
113 $set[] = "$field=" . $dbw->buildGreatest(
114 [ 'new' => $dbw->addIdentifierQuotes( $field ) . '-' . abs( $delta ) ],
115 0
116 );
117 }
118 }
119
120 if ( $set ) {
121 $dbw->update( 'site_stats', $set, [ 'ss_row_id' => 1 ], $fname );
122 }
123 }
124 ) )->doUpdate();
125
126 // Invalidate cache used by parser functions
128 }
129
134 public static function cacheUpdate( IDatabase $dbw ) {
135 $services = MediaWikiServices::getInstance();
136 $config = $services->getMainConfig();
137
138 $dbr = $services->getDBLoadBalancer()->getConnectionRef( DB_REPLICA, 'vslow' );
139 # Get non-bot users than did some recent action other than making accounts.
140 # If account creation is included, the number gets inflated ~20+ fold on enwiki.
141 $rcQuery = RecentChange::getQueryInfo();
142 $activeUsers = $dbr->selectField(
143 $rcQuery['tables'],
144 'COUNT( DISTINCT ' . $rcQuery['fields']['rc_user_text'] . ' )',
145 [
146 'rc_type != ' . $dbr->addQuotes( RC_EXTERNAL ), // Exclude external (Wikidata)
147 ActorMigration::newMigration()->isNotAnon( $rcQuery['fields']['rc_user'] ),
148 'rc_bot' => 0,
149 'rc_log_type != ' . $dbr->addQuotes( 'newusers' ) . ' OR rc_log_type IS NULL',
150 'rc_timestamp >= ' . $dbr->addQuotes(
151 $dbr->timestamp( time() - $config->get( 'ActiveUserDays' ) * 24 * 3600 ) ),
152 ],
153 __METHOD__,
154 [],
155 $rcQuery['joins']
156 );
157 $dbw->update(
158 'site_stats',
159 [ 'ss_active_users' => intval( $activeUsers ) ],
160 [ 'ss_row_id' => 1 ],
161 __METHOD__
162 );
163
164 // Invalid cache used by parser functions
166
167 return $activeUsers;
168 }
169}
Deferrable Update for closure/callback updates that should use auto-commit mode.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Class for handling updates to the site_stats table.
static factory(array $deltas)
doUpdate()
Perform the actual work.
__construct( $views, $edits, $good, $pages=0, $users=0)
static cacheUpdate(IDatabase $dbw)
merge(MergeableUpdate $update)
Merge this update with $update.
static unload()
Trigger a reload next time a field is accessed.
Definition SiteStats.php:38
const RC_EXTERNAL
Definition Defines.php:135
Interface that deferrable updates should implement.
Interface that deferrable updates can implement to signal that updates can be combined.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
addIdentifierQuotes( $s)
Escape a SQL identifier (e.g.
update( $table, $set, $conds, $fname=__METHOD__, $options=[])
Update all rows in a table that match a given condition.
buildGreatest( $fields, $values)
Build a GREATEST function statement comparing columns/values.
const DB_REPLICA
Definition defines.php:25
const DB_MASTER
Definition defines.php:29