* @param float|null $ifWritesSince Only wait if writes were done since this UNIX timestamp
* @param string|bool $wiki Wiki identifier accepted by wfGetLB
* @param string|bool $cluster Cluster name accepted by LBFactory. Default: false.
+ * @param int|null $timeout Max wait time. Default: 1 day (cli), ~10 seconds (web)
* @return bool Success (able to connect and no timeouts reached)
*/
-function wfWaitForSlaves( $ifWritesSince = false, $wiki = false, $cluster = false ) {
+function wfWaitForSlaves(
+ $ifWritesSince = null, $wiki = false, $cluster = false, $timeout = null
+) {
// B/C: first argument used to be "max seconds of lag"; ignore such values
- $ifWritesSince = ( $ifWritesSince > 1e9 ) ? $ifWritesSince : false;
+ $ifWritesSince = ( $ifWritesSince > 1e9 ) ? $ifWritesSince : null;
+
+ if ( $timeout === null ) {
+ $timeout = ( PHP_SAPI === 'cli' ) ? 86400 : 10;
+ }
if ( $cluster !== false ) {
$lb = wfGetLBFactory()->getExternalLB( $cluster );
// The DBMS may not support getMasterPos() or the whole
// load balancer might be fake (e.g. $wgAllDBsAreLocalhost).
if ( $pos !== false ) {
- return $lb->waitForAll( $pos, PHP_SAPI === 'cli' ? 86400 : null );
+ return $lb->waitForAll( $pos, $timeout );
}
}
* Results are cached for a short time in memcached, and indefinitely in the process cache
*
* @param string|bool $wiki
- * @return array
+ * @return array Map of (server index => seconds)
*/
function getLagTimes( $wiki = false ) {
# Try process cache
* @param array $serverIndexes
* @param string $wiki
*
- * @return array
+ * @return array Map of (server index => seconds)
*/
public function getLagTimes( $serverIndexes, $wiki );
}
$this->runJobsLog( "Executed $count periodic queue task(s)." );
}
+ // Bail out if there is too much DB lag
+ // @note: getLagTimes() has better caching than getMaxLag()
+ $maxLag = max( wfGetLBFactory()->getMainLB( wfWikiID() )->getLagTimes() );
+ if ( $maxLag >= 5 ) {
+ $response['reached'] = 'slave-lag-limit';
+ return $response;
+ }
+
// Flush any pending DB writes for sanity
wfGetLBFactory()->commitMasterChanges();
break;
}
- // Don't let any of the main DB slaves get backed up
+ // Don't let any of the main DB slaves get backed up.
+ // This only waits for so long before exiting and letting
+ // other wikis in the farm (on different masters) get a chance.
$timePassed = microtime( true ) - $lastTime;
if ( $timePassed >= 5 || $timePassed < 0 ) {
- wfWaitForSlaves( $lastTime );
+ if ( !wfWaitForSlaves( $lastTime, wfWikiID(), false, 5 ) ) {
+ $response['reached'] = 'slave-lag-limit';
+ break;
+ }
$lastTime = microtime( true );
}
// Don't let any queue slaves/backups fall behind