When retrieving data from memcache, invalid data is sometimes retrieved.

Because of highly concurrent accesses to cache layer, calling isset/get can sometimes fail.

To avoid this, a callback function can be used in memcached driver but it is maintained by doctrine/cache.
To prevent error, check whether returned value is of proper type.
This commit is contained in:
Benoît Burnichon
2015-06-05 14:22:19 +02:00
parent d0dee9ea2b
commit 3da671649f

View File

@@ -28,6 +28,9 @@ class databox_field implements cache_cacheableInterface
{ {
protected $id; protected $id;
/** @var Application */
protected $app;
/** /**
* @var databox * @var databox
*/ */
@@ -208,17 +211,22 @@ class databox_field implements cache_cacheableInterface
{ {
$cache_key = 'field_' . $id; $cache_key = 'field_' . $id;
$instance_id = $databox->get_sbas_id() . '_' . $id; $instance_id = $databox->get_sbas_id() . '_' . $id;
if ( ! isset(self::$_instance[$instance_id]) || (self::$_instance[$instance_id] instanceof self) === false) { if (! isset(self::$_instance[$instance_id])) {
try { try {
self::$_instance[$instance_id] = $databox->get_data_from_cache($cache_key); $field = $databox->get_data_from_cache($cache_key);
if (!$field instanceof self) {
trigger_error('Cache type returned mismatch', E_WARNING);
throw new \Exception('Retrieved $field value is invalid');
}
} catch (\Exception $e) { } catch (\Exception $e) {
self::$_instance[$instance_id] = new self($app, $databox, $id); $field = new self($app, $databox, $id);
$databox->set_data_to_cache(self::$_instance[$instance_id], $cache_key); $databox->set_data_to_cache($field, $cache_key);
} }
self::$_instance[$instance_id] = $field;
} }
self::$_instance[$instance_id]->app = $app; $field =& self::$_instance[$instance_id];
$field->app = $app;
return self::$_instance[$instance_id]; return $field;
} }
public function hydrate(Application $app) public function hydrate(Application $app)