wiki.techinc.nl/includes/libs/objectcache/APCUBagOStuff.php
Daimona Eaytoy 7dc4f6c832 Cache: Make APCUBagOStuff::set return a useful value
It took me lots of time to debug a CI failure in
I9b3bc36b552901bc6ca7609ee51e80be2979a9c4. I was deceived by
$cache->set returning true, which according to the docs means that the
store was successful. But instead, this function just returns true, even
in case of failure. Make it return the result of apcu_store, which is
already in the format true = success, false = failure.

Change-Id: I2619845c12460e1acb5af696d2c11a5a4dee1bd3
2019-04-14 19:13:48 +02:00

111 lines
3.1 KiB
PHP

<?php
/**
* Object caching using PHP's APCU accelerator.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Cache
*/
/**
* This is a wrapper for APCU's shared memory functions
*
* Use PHP serialization to avoid bugs and easily create CAS tokens.
* APCu has a memory corruption bug when the serializer is set to 'default'.
* See T120267, and upstream bug reports:
* - https://github.com/krakjoe/apcu/issues/38
* - https://github.com/krakjoe/apcu/issues/35
* - https://github.com/krakjoe/apcu/issues/111
*
* @ingroup Cache
*/
class APCUBagOStuff extends BagOStuff {
/**
* @var string String to append to each APC key. This may be changed
* whenever the handling of values is changed, to prevent existing code
* from encountering older values which it cannot handle.
*/
const KEY_SUFFIX = ':3';
protected function doGet( $key, $flags = 0, &$casToken = null ) {
$casToken = null;
$blob = apcu_fetch( $key . self::KEY_SUFFIX );
$value = $this->unserialize( $blob );
if ( $value !== false ) {
$casToken = $blob; // don't bother hashing this
}
return $value;
}
public function set( $key, $value, $exptime = 0, $flags = 0 ) {
return apcu_store(
$key . self::KEY_SUFFIX,
$this->serialize( $value ),
$exptime
);
}
public function add( $key, $value, $exptime = 0, $flags = 0 ) {
return apcu_add(
$key . self::KEY_SUFFIX,
$this->serialize( $value ),
$exptime
);
}
public function delete( $key, $flags = 0 ) {
apcu_delete( $key . self::KEY_SUFFIX );
return true;
}
public function incr( $key, $value = 1 ) {
/**
* @todo When we only support php 7 or higher remove this hack
*
* https://github.com/krakjoe/apcu/issues/166
*/
if ( apcu_exists( $key . self::KEY_SUFFIX ) ) {
return apcu_inc( $key . self::KEY_SUFFIX, $value );
} else {
return false;
}
}
public function decr( $key, $value = 1 ) {
/**
* @todo When we only support php 7 or higher remove this hack
*
* https://github.com/krakjoe/apcu/issues/166
*/
if ( apcu_exists( $key . self::KEY_SUFFIX ) ) {
return apcu_dec( $key . self::KEY_SUFFIX, $value );
} else {
return false;
}
}
protected function serialize( $value ) {
return $this->isInteger( $value ) ? (int)$value : serialize( $value );
}
protected function unserialize( $value ) {
return $this->isInteger( $value ) ? (int)$value : unserialize( $value );
}
}