MediaWiki  REL1_24
PoolCounterWork.php
Go to the documentation of this file.
00001 <?php
00027 abstract class PoolCounterWork {
00029     protected $type = 'generic';
00031     protected $cacheable = false; // does this override getCachedWork() ?
00032 
00037     public function __construct( $type, $key ) {
00038         $this->type = $type;
00039         $this->poolCounter = PoolCounter::factory( $type, $key );
00040     }
00041 
00046     abstract public function doWork();
00047 
00052     public function getCachedWork() {
00053         return false;
00054     }
00055 
00061     public function fallback() {
00062         return false;
00063     }
00064 
00072     public function error( $status ) {
00073         return false;
00074     }
00075 
00082     public function logError( $status ) {
00083         $key = $this->poolCounter->getKey();
00084 
00085         wfDebugLog( 'poolcounter', "Pool key '$key' ({$this->type}): "
00086             . $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text() );
00087     }
00088 
00104     public function execute( $skipcache = false ) {
00105         if ( $this->cacheable && !$skipcache ) {
00106             $status = $this->poolCounter->acquireForAnyone();
00107         } else {
00108             $status = $this->poolCounter->acquireForMe();
00109         }
00110 
00111         if ( !$status->isOK() ) {
00112             // Respond gracefully to complete server breakage: just log it and do the work
00113             $this->logError( $status );
00114             return $this->doWork();
00115         }
00116 
00117         switch ( $status->value ) {
00118             case PoolCounter::LOCK_HELD:
00119                 // Better to ignore nesting pool counter limits than to fail.
00120                 // Assume that the outer pool limiting is reasonable enough.
00121                 /* no break */
00122             case PoolCounter::LOCKED:
00123                 $result = $this->doWork();
00124                 $this->poolCounter->release();
00125                 return $result;
00126 
00127             case PoolCounter::DONE:
00128                 $result = $this->getCachedWork();
00129                 if ( $result === false ) {
00130                     /* That someone else work didn't serve us.
00131                      * Acquire the lock for me
00132                      */
00133                     return $this->execute( true );
00134                 }
00135                 return $result;
00136 
00137             case PoolCounter::QUEUE_FULL:
00138             case PoolCounter::TIMEOUT:
00139                 $result = $this->fallback();
00140 
00141                 if ( $result !== false ) {
00142                     return $result;
00143                 }
00144                 /* no break */
00145 
00146             /* These two cases should never be hit... */
00147             case PoolCounter::ERROR:
00148             default:
00149                 $errors = array(
00150                     PoolCounter::QUEUE_FULL => 'pool-queuefull',
00151                     PoolCounter::TIMEOUT => 'pool-timeout' );
00152 
00153                 $status = Status::newFatal( isset( $errors[$status->value] )
00154                     ? $errors[$status->value]
00155                     : 'pool-errorunknown' );
00156                 $this->logError( $status );
00157                 return $this->error( $status );
00158         }
00159     }
00160 }