MediaWiki REL1_39
MemcachedPhpBagOStuff.php
Go to the documentation of this file.
1<?php
31 protected $client;
32
43 public function __construct( $params ) {
44 parent::__construct( $params );
45
46 // Default class-specific parameters
47 $params += [
48 'compress_threshold' => 1500,
49 'connect_timeout' => 0.5,
50 'timeout' => 500000,
51 ];
52
53 $this->client = new MemcachedClient( $params );
54 $this->client->set_servers( $params['servers'] );
55 $this->client->set_debug( true );
56 }
57
58 protected function doGet( $key, $flags = 0, &$casToken = null ) {
59 $getToken = ( $casToken === self::PASS_BY_REF );
60 $casToken = null;
61
62 $routeKey = $this->validateKeyAndPrependRoute( $key );
63
64 // T257003: only require "gets" (instead of "get") when a CAS token is needed
65 $res = $getToken
66 // @phan-suppress-next-line PhanTypeMismatchArgument False positive
67 ? $this->client->get( $routeKey, $casToken )
68 : $this->client->get( $routeKey );
69
70 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
71 $this->setLastError( $this->client->_last_cmd_status );
72 }
73
74 return $res;
75 }
76
77 protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
78 $routeKey = $this->validateKeyAndPrependRoute( $key );
79
80 $res = $this->client->set( $routeKey, $value, $this->fixExpiry( $exptime ) );
81
82 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
83 $this->setLastError( $this->client->_last_cmd_status );
84 }
85
86 return $res;
87 }
88
89 protected function doDelete( $key, $flags = 0 ) {
90 $routeKey = $this->validateKeyAndPrependRoute( $key );
91
92 $res = $this->client->delete( $routeKey );
93
94 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
95 $this->setLastError( $this->client->_last_cmd_status );
96 }
97
98 return $res;
99 }
100
101 protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
102 $routeKey = $this->validateKeyAndPrependRoute( $key );
103
104 $res = $this->client->add( $routeKey, $value, $this->fixExpiry( $exptime ) );
105
106 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
107 $this->setLastError( $this->client->_last_cmd_status );
108 }
109
110 return $res;
111 }
112
113 protected function doCas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
114 $routeKey = $this->validateKeyAndPrependRoute( $key );
115
116 $res = $this->client->cas( $casToken, $routeKey, $value, $this->fixExpiry( $exptime ) );
117
118 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
119 $this->setLastError( $this->client->_last_cmd_status );
120 }
121
122 return $res;
123 }
124
125 public function incr( $key, $value = 1, $flags = 0 ) {
126 $routeKey = $this->validateKeyAndPrependRoute( $key );
127 $n = $this->client->incr( $routeKey, $value );
128
129 $res = ( $n !== false && $n !== null ) ? $n : false;
130
131 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
132 $this->setLastError( $this->client->_last_cmd_status );
133 }
134
135 return $res;
136 }
137
138 public function decr( $key, $value = 1, $flags = 0 ) {
139 $routeKey = $this->validateKeyAndPrependRoute( $key );
140 $n = $this->client->decr( $routeKey, $value );
141
142 $res = ( $n !== false && $n !== null ) ? $n : false;
143
144 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
145 $this->setLastError( $this->client->_last_cmd_status );
146 }
147
148 return $res;
149 }
150
151 protected function doIncrWithInitAsync( $key, $exptime, $step, $init ) {
152 $routeKey = $this->validateKeyAndPrependRoute( $key );
153 $watchPoint = $this->watchErrors();
154 $this->client->add( $routeKey, $init - $step, $this->fixExpiry( $exptime ) );
155 $this->client->incr( $routeKey, $step );
156 return !$this->getLastError( $watchPoint );
157 }
158
159 protected function doIncrWithInitSync( $key, $exptime, $step, $init ) {
160 $routeKey = $this->validateKeyAndPrependRoute( $key );
161
162 $watchPoint = $this->watchErrors();
163 $newValue = $this->client->incr( $routeKey, $step ) ?? false;
164 if ( $newValue === false && !$this->getLastError( $watchPoint ) ) {
165 // No key set; initialize
166 $success = $this->client->add( $routeKey, $init, $this->fixExpiry( $exptime ) );
167 $newValue = $success ? $init : false;
168 if ( $newValue === false && !$this->getLastError( $watchPoint ) ) {
169 // Raced out initializing; increment
170 $newValue = $this->client->incr( $routeKey, $step ) ?? false;
171 }
172 }
173
174 return $newValue;
175 }
176
177 protected function doChangeTTL( $key, $exptime, $flags ) {
178 $routeKey = $this->validateKeyAndPrependRoute( $key );
179
180 $res = $this->client->touch( $routeKey, $this->fixExpiry( $exptime ) );
181
182 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
183 $this->setLastError( $this->client->_last_cmd_status );
184 }
185
186 return $res;
187 }
188
189 protected function doGetMulti( array $keys, $flags = 0 ) {
190 $routeKeys = [];
191 foreach ( $keys as $key ) {
192 $routeKeys[] = $this->validateKeyAndPrependRoute( $key );
193 }
194
195 $resByRouteKey = $this->client->get_multi( $routeKeys );
196
197 $res = [];
198 foreach ( $resByRouteKey as $routeKey => $value ) {
199 $res[$this->stripRouteFromKey( $routeKey )] = $value;
200 }
201
202 if ( $this->client->_last_cmd_status !== self::ERR_NONE ) {
203 $this->setLastError( $this->client->_last_cmd_status );
204 }
205
206 return $res;
207 }
208
209 protected function serialize( $value ) {
210 return is_int( $value ) ? $value : $this->client->serialize( $value );
211 }
212
213 protected function unserialize( $value ) {
214 return $this->isInteger( $value ) ? (int)$value : $this->client->unserialize( $value );
215 }
216}
getLastError( $watchPoint=0)
Get the "last error" registry.
setLastError( $error)
Set the "last error" registry due to a problem encountered during an attempted operation.
watchErrors()
Get a "watch point" token that can be used to get the "last error" to occur after now.
isInteger( $value)
Check if a value is an integer.
Base class for memcached clients.
memcached client class implemented using (p)fsockopen()
A wrapper class for the pure-PHP memcached client, exposing a BagOStuff interface.
doSet( $key, $value, $exptime=0, $flags=0)
Set an item.
doChangeTTL( $key, $exptime, $flags)
__construct( $params)
Available parameters are:
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
doAdd( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
doCas( $casToken, $key, $value, $exptime=0, $flags=0)
Set an item if the current CAS token matches the provided CAS token.
doGet( $key, $flags=0, &$casToken=null)
Get an item.
doIncrWithInitAsync( $key, $exptime, $step, $init)
doGetMulti(array $keys, $flags=0)
Get an associative array containing the item for each of the keys that have items.
doIncrWithInitSync( $key, $exptime, $step, $init)
doDelete( $key, $flags=0)
Delete an item.