MediaWiki master
APCUBagOStuff.php
Go to the documentation of this file.
1<?php
7
28 private const KEY_SUFFIX = ':5';
29
31 private static $CAS_MAX_ATTEMPTS = 100;
32
33 public function __construct( array $params = [] ) {
34 // No use in segmenting values
35 $params['segmentationSize'] = INF;
36 parent::__construct( $params );
37 // Versions of apcu < 5.1.19 use apc.use_request_time=1 by default, causing new keys
38 // to be assigned timestamps based on the start of the PHP request/script. The longer
39 // the request has been running, the more likely that newly stored keys will instantly
40 // be seen as expired by other requests. Disable apc.use_request_time.
41 ini_set( 'apc.use_request_time', '0' );
42
43 if ( PHP_SAPI === 'cli' ) {
44 $this->attrMap[self::ATTR_DURABILITY] = ini_get( 'apc.enable_cli' )
47 } else {
49 }
50 }
51
53 protected function doGet( $key, $flags = 0, &$casToken = null ) {
54 $getToken = ( $casToken === self::PASS_BY_REF );
55 $casToken = null;
56
57 $value = apcu_fetch( $key . self::KEY_SUFFIX );
58 if ( $getToken && $value !== false ) {
59 // Note that if the driver handles serialization then this uses the PHP value
60 // as the token. This might require inspection or re-serialization in doCas().
61 $casToken = $value;
62 }
63
64 return $value;
65 }
66
68 protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
69 $ttl = $this->getExpirationAsTTL( $exptime );
70
71 return apcu_store( $key . self::KEY_SUFFIX, $value, $ttl );
72 }
73
75 protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
76 if ( apcu_exists( $key . self::KEY_SUFFIX ) ) {
77 // Avoid global write locks for high contention keys
78 return false;
79 }
80
81 $ttl = $this->getExpirationAsTTL( $exptime );
82
83 return apcu_add( $key . self::KEY_SUFFIX, $value, $ttl );
84 }
85
87 protected function doDelete( $key, $flags = 0 ) {
88 apcu_delete( $key . self::KEY_SUFFIX );
89
90 return true;
91 }
92
94 protected function doIncrWithInit( $key, $exptime, $step, $init, $flags ) {
95 // Use apcu 5.1.12 $ttl argument if apcu_inc() will initialize to $init:
96 // https://www.php.net/manual/en/function.apcu-inc.php
97 if ( $step === $init ) {
99 $ttl = $this->getExpirationAsTTL( $exptime );
100 $result = apcu_inc( $key . self::KEY_SUFFIX, $step, $success, $ttl );
101 } else {
102 $result = false;
103 for ( $i = 0; $i < self::$CAS_MAX_ATTEMPTS; ++$i ) {
104 $oldCount = apcu_fetch( $key . self::KEY_SUFFIX );
105 if ( $oldCount === false ) {
106 $count = $init;
107 $ttl = $this->getExpirationAsTTL( $exptime );
108 if ( apcu_add( $key . self::KEY_SUFFIX, $count, $ttl ) ) {
109 $result = $count;
110 break;
111 }
112 } elseif ( is_int( $oldCount ) ) {
113 $count = $oldCount + $step;
114 if ( apcu_cas( $key . self::KEY_SUFFIX, $oldCount, $count ) ) {
115 $result = $count;
116 break;
117 }
118 } else {
119 break;
120 }
121 }
122 }
123
124 return $result;
125 }
126}
127
129class_alias( APCUBagOStuff::class, 'APCUBagOStuff' );
Store data in the local server memory via APCu (php-apcu)
doIncrWithInit( $key, $exptime, $step, $init, $flags)
int|bool New value or false on failure
doDelete( $key, $flags=0)
Delete an item.bool True if the item was deleted or not found, false on failure
doGet( $key, $flags=0, &$casToken=null)
Get an item.The CAS token should be null if the key does not exist or the value is corruptmixed Retur...
doAdd( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.bool Success
doSet( $key, $value, $exptime=0, $flags=0)
Set an item.bool Success
const ATTR_DURABILITY
Key in getQoS() for durability of storage writes.
const QOS_DURABILITY_SCRIPT
Storage survives in memory until the end of the current request or CLI process (HashBagOStuff).
const QOS_DURABILITY_SERVICE
Storage survives in memory until a shared service is restarted (e.g.
const QOS_DURABILITY_NONE
Storage is disabled or never saves data, not even temporarily (EmptyBagOStuff).
Helper classs that implements most of BagOStuff for a backend.
getExpirationAsTTL( $exptime)
Convert an optionally absolute expiry time to a relative time.
const PASS_BY_REF
Idiom for doGet() to return extra information by reference.