API: (bug 20554) Expose average slave lag (avglag) as well as maxlag. Patch by Sam Reed.
This commit is contained in:
parent
1b389a2afc
commit
1b89cd274a
10 changed files with 95 additions and 0 deletions
|
|
@ -684,6 +684,7 @@ Hopefully we will remove this configuration var soon)
|
|||
* (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 ===
|
||||
|
||||
|
|
|
|||
|
|
@ -3113,6 +3113,21 @@ function wfMaxlagError( $host, $lag, $maxLag ) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -95,6 +95,24 @@ class MediaWiki {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -935,6 +935,14 @@ abstract class ApiBase {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ class ApiHelp extends ApiBase {
|
|||
public function shouldCheckMaxlag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function shouldCheckAvglag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isReadMode() {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -394,6 +394,20 @@ class ApiMain extends ApiBase {
|
|||
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'))
|
||||
|
|
@ -477,6 +491,9 @@ class ApiMain extends ApiBase {
|
|||
'maxlag' => array (
|
||||
ApiBase :: PARAM_TYPE => 'integer'
|
||||
),
|
||||
'avglag' => array (
|
||||
ApiBase :: PARAM_TYPE => 'integer'
|
||||
),
|
||||
'smaxage' => array (
|
||||
ApiBase :: PARAM_TYPE => 'integer',
|
||||
ApiBase :: PARAM_DFLT => 0
|
||||
|
|
@ -498,6 +515,7 @@ class ApiMain extends ApiBase {
|
|||
'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',
|
||||
|
|
|
|||
|
|
@ -548,6 +548,10 @@ class ApiQuery extends ApiBase {
|
|||
public function shouldCheckMaxlag() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldCheckAvglag() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getParamDescription() {
|
||||
return array (
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
|
|||
);
|
||||
}
|
||||
|
||||
$data['avglag'] = wfGetLB()->getAvgLag();
|
||||
$result = $this->getResult();
|
||||
$result->setIndexedTagName( $data, 'db' );
|
||||
return $this->getResult()->addValue( 'query', $property, $data );
|
||||
|
|
|
|||
|
|
@ -898,6 +898,27 @@ class LoadBalancer {
|
|||
}
|
||||
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
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ if( !is_null( $maxLag ) && !$mediaWiki->checkMaxLag( $maxLag ) ) {
|
|||
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' );
|
||||
|
|
|
|||
Loading…
Reference in a new issue