From 3da671649f0a2f91aa4a061b9bc6fd637db88604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Fri, 5 Jun 2015 14:22:19 +0200 Subject: [PATCH] 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. --- lib/classes/databox/field.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/classes/databox/field.php b/lib/classes/databox/field.php index dede353495..78c8826cf6 100644 --- a/lib/classes/databox/field.php +++ b/lib/classes/databox/field.php @@ -28,6 +28,9 @@ class databox_field implements cache_cacheableInterface { protected $id; + /** @var Application */ + protected $app; + /** * @var databox */ @@ -208,17 +211,22 @@ class databox_field implements cache_cacheableInterface { $cache_key = 'field_' . $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 { - 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) { - self::$_instance[$instance_id] = new self($app, $databox, $id); - $databox->set_data_to_cache(self::$_instance[$instance_id], $cache_key); + $field = new self($app, $databox, $id); + $databox->set_data_to_cache($field, $cache_key); } + self::$_instance[$instance_id] = $field; } - self::$_instance[$instance_id]->app = $app; - - return self::$_instance[$instance_id]; + $field =& self::$_instance[$instance_id]; + $field->app = $app; + return $field; } public function hydrate(Application $app)