MediaWiki
REL1_23
|
00001 <?php 00027 abstract class PoolCounterWork { 00028 protected $cacheable = false; //Does this override getCachedWork() ? 00029 00034 public function __construct( $type, $key ) { 00035 $this->poolCounter = PoolCounter::factory( $type, $key ); 00036 } 00037 00042 abstract public function doWork(); 00043 00048 public function getCachedWork() { 00049 return false; 00050 } 00051 00057 public function fallback() { 00058 return false; 00059 } 00060 00065 public function error( $status ) { 00066 return false; 00067 } 00068 00075 public function logError( $status ) { 00076 $key = $this->poolCounter->getKey(); 00077 00078 wfDebugLog( 'poolcounter', "Pool key '$key': " 00079 . $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text() ); 00080 } 00081 00097 public function execute( $skipcache = false ) { 00098 if ( $this->cacheable && !$skipcache ) { 00099 $status = $this->poolCounter->acquireForAnyone(); 00100 } else { 00101 $status = $this->poolCounter->acquireForMe(); 00102 } 00103 00104 if ( !$status->isOK() ) { 00105 // Respond gracefully to complete server breakage: just log it and do the work 00106 $this->logError( $status ); 00107 return $this->doWork(); 00108 } 00109 00110 switch ( $status->value ) { 00111 case PoolCounter::LOCKED: 00112 $result = $this->doWork(); 00113 $this->poolCounter->release(); 00114 return $result; 00115 00116 case PoolCounter::DONE: 00117 $result = $this->getCachedWork(); 00118 if ( $result === false ) { 00119 /* That someone else work didn't serve us. 00120 * Acquire the lock for me 00121 */ 00122 return $this->execute( true ); 00123 } 00124 return $result; 00125 00126 case PoolCounter::QUEUE_FULL: 00127 case PoolCounter::TIMEOUT: 00128 $result = $this->fallback(); 00129 00130 if ( $result !== false ) { 00131 return $result; 00132 } 00133 /* no break */ 00134 00135 /* These two cases should never be hit... */ 00136 case PoolCounter::ERROR: 00137 default: 00138 $errors = array( 00139 PoolCounter::QUEUE_FULL => 'pool-queuefull', 00140 PoolCounter::TIMEOUT => 'pool-timeout' ); 00141 00142 $status = Status::newFatal( isset( $errors[$status->value] ) 00143 ? $errors[$status->value] 00144 : 'pool-errorunknown' ); 00145 $this->logError( $status ); 00146 return $this->error( $status ); 00147 } 00148 } 00149 } 00150 00155 class PoolCounterWorkViaCallback extends PoolCounterWork { 00157 protected $doWork; 00159 protected $doCachedWork; 00161 protected $fallback; 00163 protected $error; 00164 00179 public function __construct( $type, $key, array $callbacks ) { 00180 parent::__construct( $type, $key ); 00181 foreach ( array( 'doWork', 'doCachedWork', 'fallback', 'error' ) as $name ) { 00182 if ( isset( $callbacks[$name] ) ) { 00183 if ( !is_callable( $callbacks[$name] ) ) { 00184 throw new MWException( "Invalid callback provided for '$name' function." ); 00185 } 00186 $this->$name = $callbacks[$name]; 00187 } 00188 } 00189 if ( !isset( $this->doWork ) ) { 00190 throw new MWException( "No callback provided for 'doWork' function." ); 00191 } 00192 $this->cacheable = isset( $this->doCachedWork ); 00193 } 00194 00195 public function doWork() { 00196 return call_user_func_array( $this->doWork, array() ); 00197 } 00198 00199 public function getCachedWork() { 00200 if ( $this->doCachedWork ) { 00201 return call_user_func_array( $this->doCachedWork, array() ); 00202 } 00203 return false; 00204 } 00205 00206 public function fallback() { 00207 if ( $this->fallback ) { 00208 return call_user_func_array( $this->fallback, array() ); 00209 } 00210 return false; 00211 } 00212 00213 public function error( $status ) { 00214 if ( $this->error ) { 00215 return call_user_func_array( $this->error, array( $status ) ); 00216 } 00217 return false; 00218 } 00219 }