MediaWiki master
MemcachedPhpBagOStuff.php
Go to the documentation of this file.
1<?php
7
9
22 protected $client;
23
34 public function __construct( $params ) {
35 parent::__construct( $params );
36
37 // Default class-specific parameters
38 $params += [
39 'compress_threshold' => 1500,
40 'connect_timeout' => 0.5,
41 'timeout' => 500000,
42 ];
43
44 $this->client = new MemcachedClient( $params );
45 $this->client->set_servers( $params['servers'] );
46 $this->client->set_debug( true );
47 }
48
50 protected function doGet( $key, $flags = 0, &$casToken = null ) {
51 $getToken = ( $casToken === self::PASS_BY_REF );
52 $casToken = null;
53
54 $routeKey = $this->validateKeyAndPrependRoute( $key );
55
56 // T257003: only require "gets" (instead of "get") when a CAS token is needed
57 $res = $getToken // @phan-suppress-next-line PhanTypeMismatchArgument False positive
58 ? $this->client->get( $routeKey, $casToken ) : $this->client->get( $routeKey );
59
60 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
61 $this->setLastError( $this->client->_last_cmd_status );
62 }
63
64 return $res;
65 }
66
68 protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
69 $routeKey = $this->validateKeyAndPrependRoute( $key );
70
71 $res = $this->client->set( $routeKey, $value, $this->fixExpiry( $exptime ) );
72
73 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
74 $this->setLastError( $this->client->_last_cmd_status );
75 }
76
77 return $res;
78 }
79
81 protected function doDelete( $key, $flags = 0 ) {
82 $routeKey = $this->validateKeyAndPrependRoute( $key );
83
84 $res = $this->client->delete( $routeKey );
85
86 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
87 $this->setLastError( $this->client->_last_cmd_status );
88 }
89
90 return $res;
91 }
92
94 protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
95 $routeKey = $this->validateKeyAndPrependRoute( $key );
96
97 $res = $this->client->add( $routeKey, $value, $this->fixExpiry( $exptime ) );
98
99 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
100 $this->setLastError( $this->client->_last_cmd_status );
101 }
102
103 return $res;
104 }
105
107 protected function doCas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
108 $routeKey = $this->validateKeyAndPrependRoute( $key );
109
110 $res = $this->client->cas( $casToken, $routeKey, $value, $this->fixExpiry( $exptime ) );
111
112 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
113 $this->setLastError( $this->client->_last_cmd_status );
114 }
115
116 return $res;
117 }
118
120 protected function doIncrWithInitAsync( $key, $exptime, $step, $init ) {
121 $routeKey = $this->validateKeyAndPrependRoute( $key );
122 $watchPoint = $this->watchErrors();
123 $this->client->add( $routeKey, $init - $step, $this->fixExpiry( $exptime ) );
124 $this->client->incr( $routeKey, $step );
125
126 return !$this->getLastError( $watchPoint );
127 }
128
130 protected function doIncrWithInitSync( $key, $exptime, $step, $init ) {
131 $routeKey = $this->validateKeyAndPrependRoute( $key );
132
133 $watchPoint = $this->watchErrors();
134 $newValue = $this->client->incr( $routeKey, $step ) ?? false;
135 if ( $newValue === false && !$this->getLastError( $watchPoint ) ) {
136 // No key set; initialize
137 $success = $this->client->add( $routeKey, $init, $this->fixExpiry( $exptime ) );
138 $newValue = $success ? $init : false;
139 if ( $newValue === false && !$this->getLastError( $watchPoint ) ) {
140 // Raced out initializing; increment
141 $newValue = $this->client->incr( $routeKey, $step ) ?? false;
142 }
143 }
144
145 return $newValue;
146 }
147
149 protected function doChangeTTL( $key, $exptime, $flags ) {
150 $routeKey = $this->validateKeyAndPrependRoute( $key );
151
152 $res = $this->client->touch( $routeKey, $this->fixExpiry( $exptime ) );
153
154 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
155 $this->setLastError( $this->client->_last_cmd_status );
156 }
157
158 return $res;
159 }
160
162 protected function doGetMulti( array $keys, $flags = 0 ) {
163 $routeKeys = [];
164 foreach ( $keys as $key ) {
165 $routeKeys[] = $this->validateKeyAndPrependRoute( $key );
166 }
167
168 $resByRouteKey = $this->client->get_multi( $routeKeys );
169
170 $res = [];
171 foreach ( $resByRouteKey as $routeKey => $value ) {
172 $res[$this->stripRouteFromKey( $routeKey )] = $value;
173 }
174
175 if ( $this->client->_last_cmd_status !== BagOStuff::ERR_NONE ) {
176 $this->setLastError( $this->client->_last_cmd_status );
177 }
178
179 return $res;
180 }
181
183 protected function serialize( $value ) {
184 return is_int( $value ) ? $value : $this->client->serialize( $value );
185 }
186
188 protected function unserialize( $value ) {
189 return $this->isInteger( $value ) ? (int)$value : $this->client->unserialize( $value );
190 }
191}
192
194class_alias( MemcachedPhpBagOStuff::class, 'MemcachedPhpBagOStuff' );
memcached client class implemented using (p)fsockopen()
setLastError( $error)
Set the "last error" registry due to a problem encountered during an attempted operation.
getLastError( $watchPoint=0)
Get the "last error" registry.
const ERR_NONE
Storage operation succeeded, or no operation was performed.
Definition BagOStuff.php:98
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.
const PASS_BY_REF
Idiom for doGet() to return extra information by reference.
Store data in a memcached server or memcached cluster.
Store data on memcached servers(s) via a pure-PHP memcached client.
unserialize( $value)
mixed Original value or false on error Special handling is usually needed for integers so incr()/decr...
doIncrWithInitAsync( $key, $exptime, $step, $init)
bool True on success, 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...
doSet( $key, $value, $exptime=0, $flags=0)
Set an item.bool Success
doCas( $casToken, $key, $value, $exptime=0, $flags=0)
Set an item if the current CAS token matches the provided CAS token.bool Success
doDelete( $key, $flags=0)
Delete an item.bool True if the item was deleted or not found, false on failure
__construct( $params)
Available parameters are:
doIncrWithInitSync( $key, $exptime, $step, $init)
int|bool New value or false on failure
serialize( $value)
string|int|false String/integer representation Special handling is usually needed for integers so inc...
doGetMulti(array $keys, $flags=0)
Get an associative array containing the item for each of the keys that have items....
doAdd( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.bool Success