Aaron Schulz has uploaded a new change for review.
https://gerrit.wikimedia.org/r/224738
Change subject: Moved LoadMonitorMySQL to a separate file
......................................................................
Moved LoadMonitorMySQL to a separate file
Change-Id: I529402416b8f12a511300b007b4f4aaf79054ad7
---
M autoload.php
M includes/db/LoadMonitor.php
A includes/db/LoadMonitorMySQL.php
3 files changed, 126 insertions(+), 106 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/38/224738/1
diff --git a/autoload.php b/autoload.php
index 6444e3e..c443734 100644
--- a/autoload.php
+++ b/autoload.php
@@ -678,7 +678,7 @@
'LoadBalancer' => __DIR__ . '/includes/db/LoadBalancer.php',
'LoadBalancerSingle' => __DIR__ . '/includes/db/LBFactorySingle.php',
'LoadMonitor' => __DIR__ . '/includes/db/LoadMonitor.php',
- 'LoadMonitorMySQL' => __DIR__ . '/includes/db/LoadMonitor.php',
+ 'LoadMonitorMySQL' => __DIR__ . '/includes/db/LoadMonitorMySQL.php',
'LoadMonitorNull' => __DIR__ . '/includes/db/LoadMonitor.php',
'LocalFile' => __DIR__ . '/includes/filerepo/file/LocalFile.php',
'LocalFileDeleteBatch' => __DIR__ .
'/includes/filerepo/file/LocalFile.php',
diff --git a/includes/db/LoadMonitor.php b/includes/db/LoadMonitor.php
index 01d2f95..4975ea1 100644
--- a/includes/db/LoadMonitor.php
+++ b/includes/db/LoadMonitor.php
@@ -64,108 +64,3 @@
return array_fill_keys( $serverIndexes, 0 );
}
}
-
-/**
- * Basic MySQL load monitor with no external dependencies
- * Uses memcached to cache the replication lag for a short time
- *
- * @ingroup Database
- */
-class LoadMonitorMySQL implements LoadMonitor {
- /** @var LoadBalancer */
- public $parent;
- /** @var BagOStuff */
- protected $srvCache;
- /** @var BagOStuff */
- protected $mainCache;
-
- public function __construct( $parent ) {
- global $wgMemc;
-
- $this->parent = $parent;
-
- $this->srvCache = ObjectCache::newAccelerator( array(), 'hash'
);
- $this->mainCache = $wgMemc ?: wfGetMainCache();
- }
-
- public function scaleLoads( &$loads, $group = false, $wiki = false ) {
- }
-
- public function getLagTimes( $serverIndexes, $wiki ) {
- if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) ==
0 ) {
- # Single server only, just return zero without caching
- return array( 0 => 0 );
- }
-
- $key = $this->getLagTimeCacheKey();
- # Randomize TTLs to reduce stampedes (4.0 - 5.0 sec)
- $ttl = mt_rand( 4e6, 5e6 ) / 1e6;
- # Keep keys around longer as fallbacks
- $staleTTL = 60;
-
- # (a) Check the local APC cache
- $value = $this->srvCache->get( $key );
- if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl
) ) {
- wfDebugLog( 'replication', __FUNCTION__ . ": got lag
times ($key) from local cache" );
- return $value['lagTimes']; // cache hit
- }
- $staleValue = $value ?: false;
-
- # (b) Check the shared cache and backfill APC
- $value = $this->mainCache->get( $key );
- if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl
) ) {
- $this->srvCache->set( $key, $value, $staleTTL );
- wfDebugLog( 'replication', __FUNCTION__ . ": got lag
times ($key) from main cache" );
-
- return $value['lagTimes']; // cache hit
- }
- $staleValue = $value ?: $staleValue;
-
- # (c) Cache key missing or expired; regenerate and backfill
- if ( $this->mainCache->lock( $key, 0, 10 ) ) {
- # Let this process alone update the cache value
- $cache = $this->mainCache;
- $unlocker = new ScopedCallback( function () use (
$cache, $key ) {
- $cache->unlock( $key );
- } );
- } elseif ( $staleValue ) {
- # Could not acquire lock but an old cache exists, so
use it
- return $value['lagTimes'];
- }
-
- $lagTimes = array();
- foreach ( $serverIndexes as $i ) {
- if ( $i == 0 ) { # Master
- $lagTimes[$i] = 0;
- } elseif ( false !== ( $conn =
$this->parent->getAnyOpenConnection( $i ) ) ) {
- $lagTimes[$i] = $conn->getLag();
- } elseif ( false !== ( $conn =
$this->parent->openConnection( $i, $wiki ) ) ) {
- $lagTimes[$i] = $conn->getLag();
- # Close the connection to avoid sleeper
connections piling up.
- # Note that the caller will pick one of these
DBs and reconnect,
- # which is slightly inefficient, but this only
matters for the lag
- # time cache miss cache, which is far less
common that cache hits.
- $this->parent->closeConnection( $conn );
- }
- }
-
- # Add a timestamp key so we know when it was cached
- $value = array( 'lagTimes' => $lagTimes, 'timestamp' =>
microtime( true ) );
- $this->mainCache->set( $key, $value, $staleTTL );
- $this->srvCache->set( $key, $value, $staleTTL );
- wfDebugLog( 'replication', __FUNCTION__ . ": re-calculated lag
times ($key)" );
-
- return $value['lagTimes'];
- }
-
- public function clearCaches() {
- $key = $this->getLagTimeCacheKey();
- $this->srvCache->delete( $key );
- $this->mainCache->delete( $key );
- }
-
- private function getLagTimeCacheKey() {
- # Lag is per-server, not per-DB, so key on the master DB name
- return wfGlobalCacheKey( 'lag-times',
$this->parent->getServerName( 0 ) );
- }
-}
diff --git a/includes/db/LoadMonitorMySQL.php b/includes/db/LoadMonitorMySQL.php
new file mode 100644
index 0000000..7c4a35c
--- /dev/null
+++ b/includes/db/LoadMonitorMySQL.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+/**
+ * Basic MySQL load monitor with no external dependencies
+ * Uses memcached to cache the replication lag for a short time
+ *
+ * @ingroup Database
+ */
+class LoadMonitorMySQL implements LoadMonitor {
+ /** @var LoadBalancer */
+ public $parent;
+ /** @var BagOStuff */
+ protected $srvCache;
+ /** @var BagOStuff */
+ protected $mainCache;
+
+ public function __construct( $parent ) {
+ global $wgMemc;
+
+ $this->parent = $parent;
+
+ $this->srvCache = ObjectCache::newAccelerator( array(), 'hash'
);
+ $this->mainCache = $wgMemc ?: wfGetMainCache();
+ }
+
+ public function scaleLoads( &$loads, $group = false, $wiki = false ) {
+ }
+
+ public function getLagTimes( $serverIndexes, $wiki ) {
+ if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) ==
0 ) {
+ # Single server only, just return zero without caching
+ return array( 0 => 0 );
+ }
+
+ $key = $this->getLagTimeCacheKey();
+ # Randomize TTLs to reduce stampedes (4.0 - 5.0 sec)
+ $ttl = mt_rand( 4e6, 5e6 ) / 1e6;
+ # Keep keys around longer as fallbacks
+ $staleTTL = 60;
+
+ # (a) Check the local APC cache
+ $value = $this->srvCache->get( $key );
+ if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl
) ) {
+ wfDebugLog( 'replication', __FUNCTION__ . ": got lag
times ($key) from local cache" );
+ return $value['lagTimes']; // cache hit
+ }
+ $staleValue = $value ?: false;
+
+ # (b) Check the shared cache and backfill APC
+ $value = $this->mainCache->get( $key );
+ if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl
) ) {
+ $this->srvCache->set( $key, $value, $staleTTL );
+ wfDebugLog( 'replication', __FUNCTION__ . ": got lag
times ($key) from main cache" );
+
+ return $value['lagTimes']; // cache hit
+ }
+ $staleValue = $value ?: $staleValue;
+
+ # (c) Cache key missing or expired; regenerate and backfill
+ if ( $this->mainCache->lock( $key, 0, 10 ) ) {
+ # Let this process alone update the cache value
+ $cache = $this->mainCache;
+ $unlocker = new ScopedCallback( function () use (
$cache, $key ) {
+ $cache->unlock( $key );
+ } );
+ } elseif ( $staleValue ) {
+ # Could not acquire lock but an old cache exists, so
use it
+ return $value['lagTimes'];
+ }
+
+ $lagTimes = array();
+ foreach ( $serverIndexes as $i ) {
+ if ( $i == 0 ) { # Master
+ $lagTimes[$i] = 0;
+ } elseif ( false !== ( $conn =
$this->parent->getAnyOpenConnection( $i ) ) ) {
+ $lagTimes[$i] = $conn->getLag();
+ } elseif ( false !== ( $conn =
$this->parent->openConnection( $i, $wiki ) ) ) {
+ $lagTimes[$i] = $conn->getLag();
+ # Close the connection to avoid sleeper
connections piling up.
+ # Note that the caller will pick one of these
DBs and reconnect,
+ # which is slightly inefficient, but this only
matters for the lag
+ # time cache miss cache, which is far less
common that cache hits.
+ $this->parent->closeConnection( $conn );
+ }
+ }
+
+ # Add a timestamp key so we know when it was cached
+ $value = array( 'lagTimes' => $lagTimes, 'timestamp' =>
microtime( true ) );
+ $this->mainCache->set( $key, $value, $staleTTL );
+ $this->srvCache->set( $key, $value, $staleTTL );
+ wfDebugLog( 'replication', __FUNCTION__ . ": re-calculated lag
times ($key)" );
+
+ return $value['lagTimes'];
+ }
+
+ public function clearCaches() {
+ $key = $this->getLagTimeCacheKey();
+ $this->srvCache->delete( $key );
+ $this->mainCache->delete( $key );
+ }
+
+ private function getLagTimeCacheKey() {
+ # Lag is per-server, not per-DB, so key on the master DB name
+ return wfGlobalCacheKey( 'lag-times',
$this->parent->getServerName( 0 ) );
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/224738
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I529402416b8f12a511300b007b4f4aaf79054ad7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits