From 9db190c7e736ec8d063187d4241b59feaf7dc2d1 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Wed, 22 Jun 2011 11:28:20 +0200 Subject: update to MediaWiki 1.17.0 --- includes/PoolCounter.php | 203 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 164 insertions(+), 39 deletions(-) (limited to 'includes/PoolCounter.php') diff --git a/includes/PoolCounter.php b/includes/PoolCounter.php index 2564fbc6..3851767f 100644 --- a/includes/PoolCounter.php +++ b/includes/PoolCounter.php @@ -1,6 +1,68 @@ acquire(); - if ( !$status->isOK() ) { - return $status; - } - if ( !empty( $status->value['overload'] ) ) { - # Overloaded. Try a dirty cache entry. - if ( $dirtyCallback ) { - if ( call_user_func( $dirtyCallback ) ) { - $this->release(); - return Status::newGood(); - } - } - - # Wait for a thread - $status = $this->wait(); - if ( !$status->isOK() ) { - $this->release(); - return $status; - } - } - # Call the main callback - call_user_func( $mainCallback ); - return $this->release(); + + protected function __construct( $conf, $type, $key ) { + $this->key = $key; + $this->workers = $conf['workers']; + $this->maxqueue = $conf['maxqueue']; + $this->timeout = $conf['timeout']; } } class PoolCounter_Stub extends PoolCounter { - public function acquire() { - return Status::newGood(); + function acquireForMe() { + return Status::newGood( PoolCounter::LOCKED ); } - public function release() { - return Status::newGood(); + function acquireForAnyone() { + return Status::newGood( PoolCounter::LOCKED ); } - public function wait() { - return Status::newGood(); + function release() { + return Status::newGood( PoolCounter::RELEASED ); } - - public function executeProtected( $mainCallback, $dirtyCallback = false ) { - call_user_func( $mainCallback ); - return Status::newGood(); + + public function __construct() { + /* No parameters needed */ } } +/** + * Handy class for dealing with PoolCounters using class members instead of callbacks. + */ +abstract class PoolCounterWork { + protected $cacheable = false; //Does this override getCachedWork() ? + + /** + * Actually perform the work, caching it if needed. + */ + abstract function doWork(); + /** + * Retrieve the work from cache + * @return mixed work result or false + */ + function getCachedWork() { + return false; + } + + /** + * A work not so good (eg. expired one) but better than an error + * message. + * @return mixed work result or false + */ + function fallback() { + return false; + } + + /** + * Do something with the error, like showing it to the user. + */ + function error( $status ) { + return false; + } + + /** + * Get the result of the work (whatever it is), or false. + */ + function execute( $skipcache = false ) { + if ( $this->cacheable && !$skipcache ) { + $status = $this->poolCounter->acquireForAnyone(); + } else { + $status = $this->poolCounter->acquireForMe(); + } + + if ( $status->isOK() ) { + switch ( $status->value ) { + case PoolCounter::LOCKED: + $result = $this->doWork(); + $this->poolCounter->release(); + return $result; + + case PoolCounter::DONE: + $result = $this->getCachedWork(); + if ( $result === false ) { + /* That someone else work didn't serve us. + * Acquire the lock for me + */ + return $this->execute( true ); + } + return $result; + + case PoolCounter::QUEUE_FULL: + case PoolCounter::TIMEOUT: + $result = $this->fallback(); + + if ( $result !== false ) { + return $result; + } + /* no break */ + + /* These two cases should never be hit... */ + case PoolCounter::ERROR: + default: + $errors = array( PoolCounter::QUEUE_FULL => 'pool-queuefull', PoolCounter::TIMEOUT => 'pool-timeout' ); + + $status = Status::newFatal( isset($errors[$status->value]) ? $errors[$status->value] : 'pool-errorunknown' ); + /* continue to the error */ + } + } + return $this->error( $status ); + } + + function __construct( $type, $key ) { + $this->poolCounter = PoolCounter::factory( $type, $key ); + } +} -- cgit v1.2.2