MediaWiki master
PoolCounterWork.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\PoolCounter;
22
25
29abstract class PoolCounterWork {
31 protected $type = 'generic';
33 protected $cacheable = false; // does this override getCachedWork() ?
35 private $poolCounter;
36
42 public function __construct( string $type, string $key, PoolCounter $poolCounter = null ) {
43 $this->type = $type;
44 // MW >= 1.35
45 $this->poolCounter = $poolCounter ??
46 MediaWikiServices::getInstance()->getPoolCounterFactory()->create( $type, $key );
47 }
48
54 abstract public function doWork();
55
61 public function getCachedWork() {
62 return false;
63 }
64
72 public function fallback( $fast ) {
73 return false;
74 }
75
82 public function error( $status ) {
83 return false;
84 }
85
91 protected function isFastStaleEnabled() {
92 return $this->poolCounter->isFastStaleEnabled();
93 }
94
101 public function logError( $status ) {
102 $key = $this->poolCounter->getKey();
103
105 'poolcounter',
106 "Pool key '$key' ({$this->type}): " .
107 $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text()
108 );
109 }
110
138 public function execute( $skipcache = false ) {
139 if ( !$this->cacheable || $skipcache ) {
140 $status = $this->poolCounter->acquireForMe();
141 } else {
142 if ( $this->isFastStaleEnabled() ) {
143 // In fast stale mode, check for existing locks by acquiring lock with 0 timeout
144 $status = $this->poolCounter->acquireForAnyone( 0 );
145 if ( $status->isOK() && $status->value === PoolCounter::TIMEOUT ) {
146 // Lock acquisition would block: try fallback
147 $staleResult = $this->fallback( true );
148 if ( $staleResult !== false ) {
149 return $staleResult;
150 }
151 // No fallback available, so wait for the lock
152 $status = $this->poolCounter->acquireForAnyone();
153 } // else behave as if $status were returned in slow mode
154 } else {
155 $status = $this->poolCounter->acquireForAnyone();
156 }
157 }
158
159 if ( !$status->isOK() ) {
160 // Respond gracefully to complete server breakage: just log it and do the work
161 $this->logError( $status );
162 return $this->doWork();
163 }
164
165 switch ( $status->value ) {
167 // Better to ignore nesting pool counter limits than to fail.
168 // Assume that the outer pool limiting is reasonable enough.
169 /* no break */
171 try {
172 return $this->doWork();
173 } finally {
174 $this->poolCounter->release();
175 }
176 // no fall-through, because try returns or throws
178 $result = $this->getCachedWork();
179 if ( $result === false ) {
180 /* That someone else work didn't serve us.
181 * Acquire the lock for me
182 */
183 return $this->execute( true );
184 }
185 return $result;
186
189 $result = $this->fallback( false );
190
191 if ( $result !== false ) {
192 return $result;
193 }
194 /* no break */
195
196 /* These two cases should never be hit... */
198 default:
199 $errors = [
200 PoolCounter::QUEUE_FULL => 'pool-queuefull',
201 PoolCounter::TIMEOUT => 'pool-timeout',
202 ];
203
204 $status = Status::newFatal( $errors[$status->value] ?? 'pool-errorunknown' );
205 $this->logError( $status );
206 return $this->error( $status );
207 }
208 }
209}
210
214class_alias( PoolCounterWork::class, 'PoolCounterWork' );
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Class for dealing with PoolCounters using class members.
doWork()
Actually perform the work, caching it if needed.
error( $status)
Do something with the error, like showing it to the user.
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
__construct(string $type, string $key, PoolCounter $poolCounter=null)
fallback( $fast)
A work not so good (eg.
isFastStaleEnabled()
Should fast stale mode be used?
getCachedWork()
Retrieve the work from cache.
Semaphore semantics to restrict how many workers may concurrently perform a task.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54