&& in_array( 'bot', $this->getUser()->getGroups() )
&& wfGetLB()->getServerCount() > 1
) {
- // Figure out how many servers have passed the lag threshold
- $numLagged = 0;
- $lagLimit = $this->getConfig()->get( 'APIMaxLagThreshold' );
- foreach ( wfGetLB()->getLagTimes() as $lag ) {
- if ( $lag > $lagLimit ) {
- ++$numLagged;
- }
- }
- // If a majority of slaves are too lagged then disallow writes
- $slaveCount = wfGetLB()->getServerCount() - 1;
- if ( $numLagged >= ceil( $slaveCount / 2 ) ) {
- $parsed = $this->parseMsg( array( 'readonlytext' ) );
- $this->dieUsage(
- $parsed['info'],
- $parsed['code'],
- /* http error */
- 0,
- array( 'readonlyreason' => "Waiting for $numLagged lagged database(s)" )
- );
+ $this->checkBotReadOnly();
+ }
+ }
+
+ /**
+ * Check whether we are readonly for bots
+ */
+ private function checkBotReadOnly() {
+ // Figure out how many servers have passed the lag threshold
+ $numLagged = 0;
+ $lagLimit = $this->getConfig()->get( 'APIMaxLagThreshold' );
+ $laggedServers = array();
+ $loadBalancer = wfGetLB();
+ foreach ( $loadBalancer->getLagTimes() as $serverIndex => $lag ) {
+ if ( $lag > $lagLimit ) {
+ ++$numLagged;
+ $laggedServers[] = $loadBalancer->getServerName( $serverIndex ) . " ({$lag}s)";
}
}
+
+ // If a majority of slaves are too lagged then disallow writes
+ $slaveCount = wfGetLB()->getServerCount() - 1;
+ if ( $numLagged >= ceil( $slaveCount / 2 ) ) {
+ $laggedServers = join( ', ', $laggedServers );
+ wfDebugLog(
+ 'api-readonly',
+ "Api request failed as read only because the following DBs are lagged: $laggedServers"
+ );
+
+ $parsed = $this->parseMsg( array( 'readonlytext' ) );
+ $this->dieUsage(
+ $parsed['info'],
+ $parsed['code'],
+ /* http error */
+ 0,
+ array( 'readonlyreason' => "Waiting for $numLagged lagged database(s)" )
+ );
+ }
}
/**
* @param string $index
* @return string
*/
- public function indexName( $index ) {
- // @FIXME: Make this protected once we move away from PHP 5.3
- // Needs to be public because of usage in closure (in DatabaseBase::replaceVars)
-
+ protected function indexName( $index ) {
// Backwards-compatibility hack
$renamed = array(
'ar_usertext_timestamp' => 'usertext_timestamp',
* @return string The new SQL statement with variables replaced
*/
protected function replaceVars( $ins ) {
- $that = $this;
$vars = $this->getSchemaVars();
return preg_replace_callback(
'!
`\{\$ (\w+) }` | # 4. addIdentifierQuotes
/\*\$ (\w+) \*/ # 5. leave unencoded
!x',
- function ( $m ) use ( $that, $vars ) {
+ function ( $m ) use ( $vars ) {
// Note: Because of <https://bugs.php.net/bug.php?id=51881>,
// check for both nonexistent keys *and* the empty string.
if ( isset( $m[1] ) && $m[1] !== '' ) {
if ( $m[1] === 'i' ) {
- return $that->indexName( $m[2] );
+ return $this->indexName( $m[2] );
} else {
- return $that->tableName( $m[2] );
+ return $this->tableName( $m[2] );
}
} elseif ( isset( $m[3] ) && $m[3] !== '' && array_key_exists( $m[3], $vars ) ) {
- return $that->addQuotes( $vars[$m[3]] );
+ return $this->addQuotes( $vars[$m[3]] );
} elseif ( isset( $m[4] ) && $m[4] !== '' && array_key_exists( $m[4], $vars ) ) {
- return $that->addIdentifierQuotes( $vars[$m[4]] );
+ return $this->addIdentifierQuotes( $vars[$m[4]] );
} elseif ( isset( $m[5] ) && $m[5] !== '' && array_key_exists( $m[5], $vars ) ) {
return $vars[$m[5]];
} else {
return null;
}
- $that = $this;
- $unlocker = new ScopedCallback( function () use ( $that, $lockKey, $fname ) {
- $that->commit( __METHOD__, 'flush' );
- $that->unlock( $lockKey, $fname );
+ $unlocker = new ScopedCallback( function () use ( $lockKey, $fname ) {
+ $this->commit( __METHOD__, 'flush' );
+ $this->unlock( $lockKey, $fname );
} );
$this->commit( __METHOD__, 'flush' );
$this->getLBInfo( 'clusterMasterHost' ) ?: $this->getServer()
);
- $that = $this;
return $cache->getWithSetCallback(
$key,
$cache::TTL_INDEFINITE,
- function () use ( $that, $cache, $key ) {
+ function () use ( $cache, $key ) {
// Get and leave a lock key in place for a short period
if ( !$cache->lock( $key, 0, 10 ) ) {
return false; // avoid master connection spike slams
}
- $conn = $that->getLazyMasterHandle();
+ $conn = $this->getLazyMasterHandle();
if ( !$conn ) {
return false; // something is misconfigured
}
Hooks::run( 'LinksUpdate', array( &$this ) );
$this->doIncrementalUpdate();
- $that = $this;
- $this->mDb->onTransactionIdle( function() use ( $that ) {
- Hooks::run( 'LinksUpdateComplete', array( &$that ) );
+ $this->mDb->onTransactionIdle( function() {
+ Hooks::run( 'LinksUpdateComplete', array( &$this ) );
} );
}
'body' => $params['content']
) );
- $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 412 ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} else {
- $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $this->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
'body' => $handle // resource
) );
- $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 412 ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} else {
- $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $this->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
) + $this->sanitizeHdrs( $params ), // extra headers merged into object
) );
- $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
} else {
- $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $this->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
);
}
- $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $request['method'] === 'PUT' && $rcode === 201 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
} else {
- $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $this->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
'headers' => array()
) );
- $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 204 ) {
// good
$status->fatal( 'backend-fail-delete', $params['src'] );
}
} else {
- $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $this->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
'headers' => $metaHdrs + $customHdrs
) );
- $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 202 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-describe', $params['src'] );
} else {
- $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $this->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
protected function doBatchPush( array $jobs, $flags ) {
$dbw = $this->getMasterDB();
- $that = $this;
$method = __METHOD__;
$dbw->onTransactionIdle(
- function () use ( $dbw, $that, $jobs, $flags, $method ) {
- $that->doBatchPushInternal( $dbw, $jobs, $flags, $method );
+ function () use ( $dbw, $jobs, $flags, $method ) {
+ $this->doBatchPushInternal( $dbw, $jobs, $flags, $method );
}
);
}
return new ArrayIterator( array() );
}
- $that = $this;
return new MappedIterator(
$unclaimed,
- function ( $value ) use ( $that ) {
- $that->jobFromSpecInternal( $value );
+ function ( $value ) {
+ $this->jobFromSpecInternal( $value );
}
);
}
return new ArrayIterator( array() );
}
- $that = $this;
return new MappedIterator(
$claimed,
- function ( $value ) use ( $that ) {
- $that->jobFromSpecInternal( $value );
+ function ( $value ) {
+ $this->jobFromSpecInternal( $value );
}
);
}
* @return MappedIterator
*/
protected function getJobIterator( RedisConnRef $conn, array $uids ) {
- $that = $this;
-
return new MappedIterator(
$uids,
- function ( $uid ) use ( $that, $conn ) {
- return $that->getJobFromUidInternal( $uid, $conn );
+ function ( $uid ) use ( $conn ) {
+ return $this->getJobFromUidInternal( $uid, $conn );
},
array( 'accept' => function ( $job ) {
return is_object( $job );
}
$lSince = microtime( true ); // lock timestamp
- // PHP 5.3: Can't use $this in a closure
- $that = $this;
- $logger = $this->logger;
- return new ScopedCallback( function() use ( $that, $logger, $key, $lSince, $expiry ) {
+ return new ScopedCallback( function() use ( $key, $lSince, $expiry ) {
$latency = .050; // latency skew (err towards keeping lock present)
$age = ( microtime( true ) - $lSince + $latency );
if ( ( $age + $latency ) >= $expiry ) {
- $logger->warning( "Lock for $key held too long ($age sec)." );
+ $this->logger->warning( "Lock for $key held too long ($age sec)." );
return; // expired; it's not "safe" to delete the key
}
- $that->unlock( $key );
+ $this->unlock( $key );
} );
}
case T_NAMESPACE:
case T_CLASS:
case T_INTERFACE:
+ case T_TRAIT:
$this->startToken = $token;
}
}
case T_CLASS:
case T_INTERFACE:
+ case T_TRAIT:
$this->tokens[] = $token;
if ( is_array( $token ) && $token[0] === T_STRING ) {
$this->classes[] = $this->namespace . $this->implodeTokens();