MediaWiki REL1_37
|
When you have many workers (threads/servers) giving service, and a cached item expensive to produce expires, you may get several workers doing the job at the same time. More...
Public Member Functions | |
acquireForAnyone ( $timeout=null) | |
I want to do this task, but if anyone else does it instead, it's also fine for me. | |
acquireForMe ( $timeout=null) | |
I want to do this task and I need to do it myself. | |
getKey () | |
isFastStaleEnabled () | |
Is fast stale mode (T250248) enabled? This may be overridden by the PoolCounterWork subclass. | |
release () | |
I have successfully finished my task. | |
Static Public Member Functions | |
static | factory (string $type, string $key) |
Create a Pool counter. | |
Public Attributes | |
const | DONE = 3 |
const | ERROR = -1 |
const | LOCK_HELD = -5 |
const | LOCKED = 1 |
const | NOT_LOCKED = -2 |
const | QUEUE_FULL = -3 |
const | RELEASED = 2 |
const | TIMEOUT = -4 |
Protected Member Functions | |
__construct (array $conf, string $type, string $key) | |
hashKeyIntoSlots ( $type, $key, $slots) | |
Given a key (any string) and the number of lots, returns a slot key (a prefix with a suffix integer from the [0..($slots-1)] range). | |
onAcquire () | |
Update any lock tracking information when the lock is acquired. | |
onRelease () | |
Update any lock tracking information when the lock is released. | |
precheckAcquire () | |
Checks that the lock request is sane. | |
Protected Attributes | |
string | $key |
All workers with the same key share the lock. | |
int | $maxqueue |
If this number of workers are already working/waiting, fail instead of wait. | |
int | $slots = 0 |
Maximum number of workers working on this task type, regardless of key. | |
int | $timeout |
Maximum time in seconds to wait for the lock. | |
int | $workers |
Maximum number of workers working on tasks with the same key simultaneously. | |
Private Attributes | |
bool | $fastStale |
Enable fast stale mode (T250248). | |
bool | $isMightWaitKey |
Whether the key is a "might wait" key. | |
Static Private Attributes | |
static bool | $acquiredMightWaitKey = 0 |
Whether this process holds a "might wait" lock key. | |
When you have many workers (threads/servers) giving service, and a cached item expensive to produce expires, you may get several workers doing the job at the same time.
Given enough requests and the item expiring fast (non-cacheable, lots of edits...) that single work can end up unfairly using most (all) of the cpu of the pool. This is also known as 'Michael Jackson effect' since this effect triggered on the english wikipedia on the day Michael Jackson died, the biographical article got hit with several edits per minutes and hundreds of read hits.
The PoolCounter provides semaphore semantics for restricting the number of workers that may be concurrently performing such single task. Only one key can be locked by any PoolCounter instance of a process, except for keys that start with "nowait:". However, only 0 timeouts (non-blocking requests) can be used with "nowait:" keys.
By default PoolCounterNull is used, which provides no locking. You can get a useful one in the PoolCounter extension.
Definition at line 47 of file PoolCounter.php.
|
protected |
array | $conf | |
string | $type | The class of actions to limit concurrency for (task type) |
string | $key |
Definition at line 94 of file PoolCounter.php.
References $key, and hashKeyIntoSlots().
|
abstract |
I want to do this task, but if anyone else does it instead, it's also fine for me.
I will read its cached data.
int | null | $timeout | Wait timeout, or null to use value passed to the constructor |
Reimplemented in PoolCounterNull, and PoolCounterRedis.
|
abstract |
I want to do this task and I need to do it myself.
int | null | $timeout | Wait timeout, or null to use value passed to the constructor |
Reimplemented in PoolCounterNull, and PoolCounterRedis.
|
static |
Create a Pool counter.
This should only be called from the PoolWorks.
string | $type | The class of actions to limit concurrency for (task type) |
string | $key |
Definition at line 119 of file PoolCounter.php.
References $key, $type, and $wgPoolCounterConf.
Referenced by PoolCounterWork\__construct().
PoolCounter::getKey | ( | ) |
|
protected |
Given a key (any string) and the number of lots, returns a slot key (a prefix with a suffix integer from the [0..($slots-1)] range).
This is used for a global limit on the number of instances of a given type that can acquire a lock. The hashing is deterministic so that PoolCounter::$workers is always an upper limit of how many instances with the same key can acquire a lock.
string | $type | The class of actions to limit concurrency for (task type) |
string | $key | PoolCounter instance key (any string) |
int | $slots | The number of slots (max allowed value is 65536) |
Definition at line 227 of file PoolCounter.php.
References $key, $slots, and $type.
Referenced by __construct().
PoolCounter::isFastStaleEnabled | ( | ) |
Is fast stale mode (T250248) enabled? This may be overridden by the PoolCounterWork subclass.
Definition at line 237 of file PoolCounter.php.
References $fastStale.
|
finalprotected |
Update any lock tracking information when the lock is acquired.
Definition at line 203 of file PoolCounter.php.
References $isMightWaitKey.
Referenced by PoolCounterRedis\waitForSlotOrNotif().
|
finalprotected |
Update any lock tracking information when the lock is released.
Definition at line 211 of file PoolCounter.php.
References $isMightWaitKey.
Referenced by PoolCounterRedis\release(), and PoolCounterRedis\waitForSlotOrNotif().
|
finalprotected |
Checks that the lock request is sane.
Definition at line 178 of file PoolCounter.php.
Referenced by PoolCounterRedis\acquireForAnyone(), and PoolCounterRedis\acquireForMe().
|
abstract |
I have successfully finished my task.
Lets another one grab the lock, and returns the workers waiting on acquireForAnyone()
Reimplemented in PoolCounterNull, and PoolCounterRedis.
|
staticprivate |
Whether this process holds a "might wait" lock key.
Definition at line 82 of file PoolCounter.php.
|
private |
Enable fast stale mode (T250248).
This may be overridden by the work class.
Definition at line 87 of file PoolCounter.php.
Referenced by isFastStaleEnabled().
|
private |
Whether the key is a "might wait" key.
Definition at line 78 of file PoolCounter.php.
Referenced by onAcquire(), and onRelease().
|
protected |
All workers with the same key share the lock.
Definition at line 60 of file PoolCounter.php.
Referenced by PoolCounterRedis\__construct(), __construct(), factory(), getKey(), and hashKeyIntoSlots().
|
protected |
If this number of workers are already working/waiting, fail instead of wait.
Definition at line 71 of file PoolCounter.php.
|
protected |
Maximum number of workers working on this task type, regardless of key.
0 means unlimited. Max allowed value is 65536. The way the slot limit is enforced is overzealous - this option should be used with caution.
Definition at line 69 of file PoolCounter.php.
Referenced by hashKeyIntoSlots().
|
protected |
Maximum time in seconds to wait for the lock.
Definition at line 73 of file PoolCounter.php.
Referenced by PoolCounterRedis\acquireForAnyone(), PoolCounterRedis\acquireForMe(), and PoolCounterRedis\waitForSlotOrNotif().
|
protected |
Maximum number of workers working on tasks with the same key simultaneously.
Definition at line 62 of file PoolCounter.php.
const PoolCounter::DONE = 3 |
Definition at line 51 of file PoolCounter.php.
Referenced by PoolCounterWork\execute(), and PoolCounterRedis\waitForSlotOrNotif().
const PoolCounter::ERROR = -1 |
Definition at line 53 of file PoolCounter.php.
Referenced by PoolCounterWork\execute().
const PoolCounter::LOCK_HELD = -5 |
Definition at line 57 of file PoolCounter.php.
Referenced by PoolCounterWork\execute(), and PoolCounterRedis\waitForSlotOrNotif().
const PoolCounter::LOCKED = 1 |
Definition at line 49 of file PoolCounter.php.
Referenced by PoolCounterNull\acquireForAnyone(), PoolCounterNull\acquireForMe(), PoolCounterWork\execute(), and PoolCounterRedis\waitForSlotOrNotif().
const PoolCounter::NOT_LOCKED = -2 |
Definition at line 54 of file PoolCounter.php.
Referenced by PoolCounterRedis\release().
const PoolCounter::QUEUE_FULL = -3 |
Definition at line 55 of file PoolCounter.php.
Referenced by PoolCounterWork\execute(), and PoolCounterRedis\waitForSlotOrNotif().
const PoolCounter::RELEASED = 2 |
Definition at line 50 of file PoolCounter.php.
Referenced by PoolCounterNull\release(), and PoolCounterRedis\release().
const PoolCounter::TIMEOUT = -4 |
Definition at line 56 of file PoolCounter.php.
Referenced by PoolCounterWork\execute(), and PoolCounterRedis\waitForSlotOrNotif().