From 332c4965068fb1379657807dd8eec9ffb03ac42e Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Sun, 31 Aug 2008 19:29:37 +0000 Subject: [PATCH] * Maintain active user count for Special:Statistics (bug 13585) * Add a global to add update functions to updateSpecialPages.php --- includes/DefaultSettings.php | 8 ++ includes/SiteStats.php | 28 ++++-- includes/specials/SpecialStatistics.php | 7 +- languages/messages/MessagesEn.php | 3 +- .../archives/patch-ss_active_users.sql | 6 ++ maintenance/postgres/tables.sql | 1 + maintenance/tables.sql | 3 + maintenance/updateSpecialPages.php | 93 ++++++++++--------- maintenance/updaters.inc | 4 + 9 files changed, 100 insertions(+), 53 deletions(-) create mode 100644 maintenance/archives/patch-ss_active_users.sql diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index e774f83f4f..040c91cec7 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1616,6 +1616,14 @@ $wgJobClasses = array( 'fixDoubleRedirect' => 'DoubleRedirectJob', ); +/** + * Additional functions to be performed with updateSpecialPages. + * Expensive Querypages are already updated. + */ +$wgSpecialPageCacheUpdates = array( + 'Statistics' => 'SiteStatsUpdate::cacheUpdate' +); + /** * To use inline TeX, you need to compile 'texvc' (in the 'math' subdirectory of * the MediaWiki package and have latex, dvips, gs (ghostscript), andconvert diff --git a/includes/SiteStats.php b/includes/SiteStats.php index e64a624653..5ae3203909 100644 --- a/includes/SiteStats.php +++ b/includes/SiteStats.php @@ -93,6 +93,11 @@ class SiteStats { self::load(); return self::$row->ss_users; } + + static function activeUsers() { + self::load(); + return self::$row->ss_active_users; + } static function images() { self::load(); @@ -248,13 +253,20 @@ class SiteStatsUpdate { $dbw->query( $sql, $fname ); $dbw->commit(); } - - /* - global $wgDBname, $wgTitle; - if ( $this->mGood && $wgDBname == 'enwiki' ) { - $good = $dbw->selectField( 'site_stats', 'ss_good_articles', '', $fname ); - error_log( $good . ' ' . $wgTitle->getPrefixedDBkey() . "\n", 3, '/home/wikipedia/logs/million.log' ); - } - */ + } + + public static function cacheUpdate( $dbw ) { + $dbr = wfGetDB( DB_SLAVE, array( 'SpecialStatistics', 'vslow') ); + # Get non-bot users than did some recent action other than making accounts. + # If account creation is included, the number gets inflated ~20+ fold on enwiki. + $activeUsers = $dbr->selectField( 'recentchanges', 'COUNT( DISTINCT rc_user_text )', + array( 'rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'" ), + __METHOD__ ); + $dbw->begin(); + $dbw->update( 'site_stats', + array( 'ss_active_users' => intval($activeUsers) ), + array('1 = 1'), __METHOD__, array( 'LIMIT' => 1 ) + ); + $dbw->commit(); } } diff --git a/includes/specials/SpecialStatistics.php b/includes/specials/SpecialStatistics.php index cb1ca88d9a..a920e83138 100644 --- a/includes/specials/SpecialStatistics.php +++ b/includes/specials/SpecialStatistics.php @@ -23,13 +23,15 @@ function wfSpecialStatistics( $par = '' ) { $images = SiteStats::images(); $total = SiteStats::pages(); $users = SiteStats::users(); + $activeUsers = SiteStats::activeUsers(); $admins = SiteStats::numberingroup('sysop'); $numJobs = SiteStats::jobs(); if( $wgRequest->getVal( 'action' ) == 'raw' ) { $wgOut->disable(); header( 'Pragma: nocache' ); - echo "total=$total;good=$good;views=$views;edits=$edits;users=$users;admins=$admins;images=$images;jobs=$numJobs\n"; + echo "total=$total;good=$good;views=$views;edits=$edits;users=$users;"; + echo "activeusers=$activeusers;admins=$admins;images=$images;jobs=$numJobs\n"; return; } else { $text = "__NOTOC__\n"; @@ -51,7 +53,8 @@ function wfSpecialStatistics( $par = '' ) { $wgLang->formatNum( $admins ), '[[' . wfMsgForContent( 'grouppage-sysop' ) . ']]', # TODO somehow remove, kept for backwards compatibility $wgLang->formatNum( @sprintf( '%.2f', $admins / $users * 100 ) ), - User::makeGroupLinkWiki( 'sysop' ) + User::makeGroupLinkWiki( 'sysop' ), + $wgLang->formatNum( $activeUsers ) )."\n"; global $wgDisableCounters, $wgMiserMode, $wgUser, $wgLang, $wgContLang; diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 3f7f2f09a7..72a7e231b0 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -1926,7 +1926,8 @@ There have been a total of '''\$3''' {{PLURAL:\$3|page view|page views}}, and '' That comes to '''\$5''' average edits per page, and '''\$6''' views per edit. The [http://www.mediawiki.org/wiki/Manual:Job_queue job queue] length is '''\$7'''.", -'userstatstext' => "There {{PLURAL:$1|is '''1''' registered [[Special:ListUsers|user]]|are '''$1''' registered [[Special:ListUsers|users]]}}, of which '''$2''' (or '''$4%''') {{PLURAL:$2|has|have}} $5 rights.", +'userstatstext' => "There {{PLURAL:$1|is '''1''' registered [[Special:ListUsers|user]]|are '''$1''' registered [[Special:ListUsers|users]]}}, of which '''$2''' (or '''$4%''') {{PLURAL:$2|has|have}} $5 rights. +There {{PLURAL:$6|is|are}} currently about '''$6''' active registered user {{PLURAL:$6|account|accounts}}.", 'statistics-mostpopular' => 'Most viewed pages', 'statistics-footer' => '', # do not translate or duplicate this message to other languages diff --git a/maintenance/archives/patch-ss_active_users.sql b/maintenance/archives/patch-ss_active_users.sql new file mode 100644 index 0000000000..7143905248 --- /dev/null +++ b/maintenance/archives/patch-ss_active_users.sql @@ -0,0 +1,6 @@ +-- More statistics, for version 1.14 + +ALTER TABLE /*$wgDBprefix*/site_stats ADD ss_active_users bigint default '-1'; +SELECT @activeusers := COUNT( DISTINCT rc_user_text ) FROM /*$wgDBprefix*/recentchanges +WHERE rc_user != 0 AND rc_bot = 0 AND rc_log_type != 'newusers'; +UPDATE /*$wgDBprefix*/site_stats SET ss_active_users=@activeusers; diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql index 8dbf77fa01..44156c7189 100644 --- a/maintenance/postgres/tables.sql +++ b/maintenance/postgres/tables.sql @@ -213,6 +213,7 @@ CREATE TABLE site_stats ( ss_good_articles INTEGER DEFAULT 0, ss_total_pages INTEGER DEFAULT -1, ss_users INTEGER DEFAULT -1, + ss_active_users INTEGER DEFAULT -1, ss_admins INTEGER DEFAULT -1, ss_images INTEGER DEFAULT 0 ); diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 4035d25db5..d3512c5077 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -596,6 +596,9 @@ CREATE TABLE /*$wgDBprefix*/site_stats ( -- Number of users, theoretically equal to SELECT COUNT(*) FROM user; ss_users bigint default '-1', + + -- Number of users that still edit + ss_active_users bigint default '-1', -- Deprecated, no longer updated as of 1.5 ss_admins int default '-1', diff --git a/maintenance/updateSpecialPages.php b/maintenance/updateSpecialPages.php index ac7ee11f0e..3eaa62056b 100644 --- a/maintenance/updateSpecialPages.php +++ b/maintenance/updateSpecialPages.php @@ -25,7 +25,31 @@ if(@$options['help']) { $wgOut->disable(); $dbw = wfGetDB( DB_MASTER ); -foreach ( $wgQueryPages as $page ) { +foreach( $wgSpecialPageCacheUpdates as $special => $call ) { + if( !is_callable($call) ) { + print "Uncallable function $call!\n"; + continue; + } + $t1 = explode( ' ', microtime() ); + call_user_func( $call, $dbw ); + $t2 = explode( ' ', microtime() ); + printf( '%-30s ', $special ); + $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]); + $hours = intval( $elapsed / 3600 ); + $minutes = intval( $elapsed % 3600 / 60 ); + $seconds = $elapsed - $hours * 3600 - $minutes * 60; + if ( $hours ) { + print $hours . 'h '; + } + if ( $minutes ) { + print $minutes . 'm '; + } + printf( "completed in %.2fs\n", $seconds ); + # Wait for the slave to catch up + wfWaitForSlaves( 5 ); +} + +foreach( $wgQueryPages as $page ) { @list( $class, $special, $limit ) = $page; # --list : just show the name of pages @@ -50,33 +74,30 @@ foreach ( $wgQueryPages as $page ) { } $queryPage = new $class; - if( !(isset($options['only'])) or ($options['only'] == $queryPage->getName()) ) { - printf( '%-30s ', $special ); - - if ( $queryPage->isExpensive() ) { - $t1 = explode( ' ', microtime() ); - # Do the query - $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit ); - $t2 = explode( ' ', microtime() ); - - if ( $num === false ) { - print "FAILED: database error\n"; - } else { - print "got $num rows in "; - - $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]); - $hours = intval( $elapsed / 3600 ); - $minutes = intval( $elapsed % 3600 / 60 ); - $seconds = $elapsed - $hours * 3600 - $minutes * 60; - if ( $hours ) { - print $hours . 'h '; - } - if ( $minutes ) { - print $minutes . 'm '; - } - printf( "%.2fs\n", $seconds ); + if( !isset($options['only']) or $options['only'] == $queryPage->getName() ) { + printf( '%-30s ', $special ); + if ( $queryPage->isExpensive() ) { + $t1 = explode( ' ', microtime() ); + # Do the query + $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit ); + $t2 = explode( ' ', microtime() ); + if ( $num === false ) { + print "FAILED: database error\n"; + } else { + print "got $num rows in "; + + $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]); + $hours = intval( $elapsed / 3600 ); + $minutes = intval( $elapsed % 3600 / 60 ); + $seconds = $elapsed - $hours * 3600 - $minutes * 60; + if ( $hours ) { + print $hours . 'h '; + } + if ( $minutes ) { + print $minutes . 'm '; + } + printf( "%.2fs\n", $seconds ); } - # Reopen any connections that have closed if ( !wfGetLB()->pingAll()) { print "\n"; @@ -89,22 +110,10 @@ foreach ( $wgQueryPages as $page ) { # Commit the results $dbw->immediateCommit(); } - # Wait for the slave to catch up - /* - $slaveDB = wfGetDB( DB_SLAVE, array('QueryPage::recache', 'vslow' ) ); - while( $slaveDB->getLag() > 600 ) { - print "Slave lagged, waiting...\n"; - sleep(30); - - } - */ wfWaitForSlaves( 5 ); - - } else { - print "cheap, skipped\n"; - } + } else { + print "cheap, skipped\n"; + } } } - - diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index f948840674..e22412c1f5 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -143,6 +143,9 @@ $wgMysqlUpdates = array( array( 'maybe_do_profiling_memory_update' ), array( 'do_filearchive_indices_update' ), array( 'update_password_format' ), + + // 1.14 + array( 'add_field', 'site_stats', 'ss_active_users', 'patch-ss_active_users.sql' ), ); @@ -1463,6 +1466,7 @@ function do_postgres_updates() { array("revision", "rev_len", "INTEGER"), array("revision", "rev_deleted", "SMALLINT NOT NULL DEFAULT 0"), array("user_newtalk", "user_last_timestamp", "TIMESTAMPTZ"), + array("site_stats", "ss_active_users", "INTERGER DEFAULT '-1'"), ); -- 2.20.1