* (bug 19004) Added support for tags
* (bug 21083) list=allusers no longer returns current timestamp for users
without registration date
+* (bug 20554) Expose average slave lag (avglag) as well as maxlag
=== Languages updated in 1.16 ===
}
}
+/**
+ * Displays a avglag error
+ *
+ * @param $lag Integer: avglag (actual)
+ * @param $avgLag Integer: avglag (requested)
+ */
+function wfAvglagError( $lag, $avgLag ) {
+ header( 'HTTP/1.1 503 Service Unavailable' );
+ header( 'Retry-After: ' . max( intval( $avgLag ), 5 ) );
+ header( 'X-Database-Lag: ' . intval( $lag ) );
+ header( 'Content-Type: text/plain' );
+
+ echo "Lagged: $lag seconds average\n";
+}
+
/**
* Throws a warning that $function is deprecated
* @param $function String
return true;
}
}
+
+ /**
+ * Check if the average lag of database slaves is higher that $avgLag, and
+ * if it's the case, output an error message
+ *
+ * @param $avgLag int: maximum lag allowed for the request, as supplied by
+ * the client
+ * @return bool true if the request can continue
+ */
+ function checkAvgLag( $avgLag ) {
+ list( $host, $lag ) = wfGetLB()->getAvgLag();
+ if( $lag > $avgLag ) {
+ wfAvglagError( $lag, $avgLag );
+ return false;
+ } else {
+ return true;
+ }
+ }
/**
* Checks some initial queries
public function shouldCheckMaxlag() {
return true;
}
+
+ /**
+ * Indicates if this module needs avglag to be checked
+ * @return bool
+ */
+ public function shouldCheckAvglag() {
+ return true;
+ }
/**
* Indicates whether this module requires read rights
public function shouldCheckMaxlag() {
return false;
}
+
+ public function shouldCheckAvglag() {
+ return false;
+ }
public function isReadMode() {
return false;
return;
}
}
+
+ if( $module->shouldCheckAvglag() && isset( $params['avglag'] ) ) {
+ // Check for avglag
+ global $wgShowHostnames;
+ $avgLag = $params['avglag'];
+ $lag = wfGetLB()->getAvgLag();
+ if ( $lag > $avgLag ) {
+ header( 'Retry-After: ' . max( intval( $avgLag ), 5 ) );
+ header( 'X-Database-Lag: ' . intval( $lag ) );
+
+ $this->dieUsage( "Lag: $lag seconds average", 'avglag' );
+ return;
+ }
+ }
global $wgUser;
if ($module->isReadMode() && !$wgUser->isAllowed('read'))
'maxlag' => array (
ApiBase :: PARAM_TYPE => 'integer'
),
+ 'avglag' => array (
+ ApiBase :: PARAM_TYPE => 'integer'
+ ),
'smaxage' => array (
ApiBase :: PARAM_TYPE => 'integer',
ApiBase :: PARAM_DFLT => 0
'action' => 'What action you would like to perform',
'version' => 'When showing help, include version for each module',
'maxlag' => 'Maximum lag',
+ 'avglag' => 'Average lag',
'smaxage' => 'Set the s-maxage header to this many seconds. Errors are never cached',
'maxage' => 'Set the max-age header to this many seconds. Errors are never cached',
'requestid' => 'Request ID to distinguish requests. This will just be output back to you',
public function shouldCheckMaxlag() {
return true;
}
+
+ public function shouldCheckAvglag() {
+ return true;
+ }
public function getParamDescription() {
return array (
);
}
+ $data['avglag'] = wfGetLB()->getAvgLag();
$result = $this->getResult();
$result->setIndexedTagName( $data, 'db' );
return $this->getResult()->addValue( 'query', $property, $data );
}
return array( $host, $maxLag );
}
+
+ /**
+ * Gets the average lag of slaves.
+ * May attempt to open connections to slaves on the default DB.
+ */
+ function getAvgLag() {
+ $lag = 0;
+ $count = 0;
+ foreach ( $this->mServers as $i => $conn ) {
+ $conn = $this->getAnyOpenConnection( $i );
+ if ( !$conn ) {
+ $conn = $this->openConnection( $i );
+ }
+ if ( !$conn ) {
+ continue;
+ }
+ $lag += $conn->getLag();
+ $count++;
+ }
+ return ($count > 1) ? $lag / $count : $lag;
+ }
/**
* Get lag time for each server
exit;
}
+$avgLag = $wgRequest->getVal( 'avglag' );
+if( !is_null( $avgLag ) && !$mediaWiki->checkAvgLag( $avgLag ) ) {
+ exit;
+}
+
# Query string fields
$action = $wgRequest->getVal( 'action', 'view' );
$title = $wgRequest->getVal( 'title' );