8000 [Cache] Allow and use generators in AbstractAdapter · symfony/symfony@996a8f2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 996a8f2

Browse files
[Cache] Allow and use generators in AbstractAdapter
1 parent cc84be9 commit 996a8f2

File tree

8 files changed

+84
-59
lines changed

8 files changed

+84
-59
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"symfony/yaml": "self.version"
7777
},
7878
"require-dev": {
79-
"cache/integration-tests": "^0.6",
79+
"cache/integration-tests": "dev-master",
8080
"doctrine/cache": "~1.6",
8181
"doctrine/data-fixtures": "1.0.*",
8282
"doctrine/dbal": "~2.4",

src/Symfony/Component/Cache/Adapter/AbstractAdapter.php

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function ($deferred, $namespace) {
6464
*
6565
* @param array $ids The cache identifiers to fetch.
6666
*
67-
* @return array The corresponding values found in the cache.
67+
* @return array|\Traversable The corresponding values found in the cache.
6868
*/
6969
abstract protected function doFetch(array $ids);
7070

@@ -80,9 +80,11 @@ abstract protected function doHave($id);
8080
/**
8181
* Deletes all items in the pool.
8282
*
83+
* @param string The prefix used for all identifiers managed by this pool.
84+
*
8385
* @return bool True if the pool was successfully cleared, false otherwise.
8486
*/
85-
abstract protected function doClear();
87+
abstract protected function doClear($namespace);
8688

8789
/**
8890
* Removes multiple items from the pool.
@@ -108,14 +110,10 @@ abstract protected function doSave(array $values, $lifetime);
108110
*/
109111
public function getItem($key)
110112
{
111-
$id = $this->getId($key);
112-
113113
if ($this->deferred) {
114114
$this->commit();
115115
}
116-
if (isset($this->deferred[$key])) {
117-
return $this->deferred[$key];
118-
}
116+
$id = $this->getId($key);
119117

120118
$f = $this->createCacheItem;
121119
$isHit = false;
@@ -136,40 +134,35 @@ public function getItems(array $keys = array())
136134
if ($this->deferred) {
137135
$this->commit();
138136
}
139-
$f = $this->createCacheItem;
140137
$ids = array();
141-
$items = array();
142138

143139
foreach ($keys as $key) {
144-
$id = $this->getId($key);
145-
146-
if (isset($this->deferred[$key])) {
147-
$items[$key] = $this->deferred[$key];
148-
} else {
149 9E88 -
$ids[$key] = $id;
150-
}
140+
$ids[$key] = $this->getId($key);
151141
}
142+
$items = $this->doFetch($ids);
143+
$ids = array_flip($ids);
152144

153-
$values = $this->doFetch($ids);
154-
155-
foreach ($ids as $key => $id) {
156-
$isHit = isset($values[$id]);
157-
$items[$key] = $f($key, $isHit ? $values[$id] : null, $isHit);
158-
}
159-
160-
return $items;
145+
return $this->generateItems($items, $ids);
161146
}
162147

163148
/**
164149
* {@inheritdoc}
165150
*/
166151
public function hasItem($key)
167152
{
168-
if ($this->deferred) {
169-
$this->commit();
153+
$id = $this->getId($key);
154+
155+
if (isset($this->deferred[$key])) {
156+
$item = (array) $this->deferred[$key];
157+
$ok = $this->doSave(array($item[CacheItem::CAST_PREFIX.'key'] => $item[CacheItem::CAST_PREFIX.'value']), $item[CacheItem::CAST_PREFIX.'lifetime']);
158+
unset($this->deferred[$key]);
159+
160+
if (true === $ok || array() === $ok) {
161+
return true;
162+
}
170163
}
171164

172-
return $this->doHave($this->getId($key));
165+
return $this->doHave($id);
173166
}
174167

175168
/**
@@ -179,7 +172,7 @@ public function clear()
179172
{
180173
$this->deferred = array();
181174

182-
return $this->doClear();
175+
return $this->doClear($this->namespace);
183176
}
184177

185178
/**
@@ -198,7 +191,7 @@ public function deleteItems(array $keys)
198191
$ids = array();
199192

200193
foreach ($keys as $key) {
201-
$ids[] = $this->getId($key);
194+
$ids[$key] = $this->getId($key);
202195
unset($this->deferred[$key]);
203196
}
204197

@@ -214,10 +207,12 @@ public function save(CacheItemInterface $item)
214207
return false;
215208
}
216209
$key = $item->getKey();
210+
if ($this->deferred) {
211+
$this->commit();
212+
}
217213
$this->deferred[$key] = $item;
218-
$this->commit();
219214

220-
return !isset($this->deferred[$key]);
215+
return $this->commit();
221216
}
222217

223218
/**
@@ -230,10 +225,7 @@ public function saveDeferred(CacheItemInterface $item)
230225
}
231226
try {
232227
$item = clone $item;
233-
} catch (\Error $e) {
234228
} catch (\Exception $e) {
235-
}
236-
if (isset($e)) {
237229
@trigger_error($e->__toString());
238230

239231
return false;
@@ -250,7 +242,6 @@ public function commit()
250242
{
251243
$f = $this->mergeByLifetime;
252244
$ko = array();
253-
$namespaceLen = strlen($this->namespace);
254245

255246
foreach ($f($this->deferred, $this->namespace) as $lifetime => $values) {
256247
if (true === $ok = $this->doSave($values, $lifetime)) {
@@ -259,13 +250,28 @@ public function commit()
259250
if (false === $ok) {
260251
$ok = array_keys($values);
261252
}
262-
foreach ($ok as $failedId) {
263-
$key = substr($failedId, $namespaceLen);
264-
$ko[$key] = $this->deferred[$key];
253+
foreach ($ok as $id) {
254+
$ko[$lifetime][] = array($id => $values[$id]);
255+
}
256+
}
257+
258+
$this->deferred = array();
259+
$ok = true;
260+
261+
// When bulk-save failed, retry each item individually
262+
foreach ($ko as $lifetime => $values) {
263+
foreach ($values as $v) {
264+
if (in_array($this->doSave($v, $lifetime), array(true, array()), true)) {
265+
$ok = false;
266+
267+
foreach ($v as $key => $value) {
268+
@trigger_error(sprintf('Failed to cache key "%s" of type "%s"', is_object($value) ? get_class($value) : gettype($value)));
269+
}
270+
}
265271
}
266272
}
267273

268-
return !$this->deferred = $ko;
274+
return $ok;
269275
}
270276

271277
public function __destruct()
@@ -289,4 +295,18 @@ private function getId($key)
289295

290296
return $this->namespace.$key;
291297
}
298+
299+
private function generateItems($items, &$keys)
300+
{
301+
$f = $this->createCacheItem;
302+
303+
foreach ($items as $id => $value) {
304+
yield $keys[$id] => $f($keys[$id], $value, true);
305+
unset($keys[$id]);
306+
}
307+
308+
foreach ($keys as $key) {
309+
yield $key => $f($key, null, false);
310+
}
311+
}
292312
}

src/Symfony/Component/Cache/Adapter/ApcuAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ protected function doHave($id)
4848
/**
4949
* {@inheritdoc}
5050
*/
51-
protected function doClear()
51+
protected function doClear($namespace)
5252
{
5353
return apcu_clear_cache();
5454
}

src/Symfony/Component/Cache/Adapter/ArrayAdapter.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,10 @@ public function save(CacheItemInterface $item)
118118
if (!$item instanceof CacheItem) {
119119
return false;
120120
}
121-
static $prefix = "\0Symfony\Component\Cache\CacheItem\0";
122121
$item = (array) $item;
123-
$key = $item[$prefix.'key'];
124-
$value = $item[$prefix.'value'];
125-
$lifetime = $item[$prefix.'lifetime'];
122+
$key = $item[CacheItem::CAST_PREFIX.'key'];
123+
$value = $item[CacheItem::CAST_PREFIX.'value'];
124+
$lifetime = $item[CacheItem::CAST_PREFIX.'lifetime'];
126125

127126
if (0 > $lifetime) {
128127
return true;

src/Symfony/Component/Cache/Adapter/DoctrineAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected function doHave($id)
4545
/**
4646
* {@inheritdoc}
4747
*/
48-
protected function doClear()
48+
protected function doClear($namespace)
4949
{
5050
return $this->provider->flushAll();
5151
}

src/Symfony/Component/Cache/Adapter/ProxyAdapter.php

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,7 @@ public function getItem($key)
5656
*/
5757
public function getItems(array $keys = array())
5858
{
59-
$f = $this->createCacheItem;
60-
$items = array();
61-
62-
foreach ($this->pool->getItems($keys) as $key => $item) {
63-
$items[$key] = $f($key, $item->get(), $item->isHit());
64-
}
65-
66-
return $items;
59+
return $this->generateItems($this->pool->getItems($keys));
6760
}
6861

6962
/**
@@ -127,12 +120,20 @@ private function doSave(CacheItemInterface $item, $method)
127120
if (!$item instanceof CacheItem) {
128121
return false;
129122
}
130-
static $prefix = "\0Symfony\Component\Cache\CacheItem\0";
131123
$item = (array) $item;
132-
$poolItem = $this->pool->getItem($item[$prefix.'key']);
133-
$poolItem->set($item[$prefix.'value']);
134-
$poolItem->expiresAfter($item[$prefix.'lifetime']);
124+
$poolItem = $this->pool->getItem($item[CacheItem::CAST_PREFIX.'key']);
125+
$poolItem->set($item[CacheItem::CAST_PREFIX.'value']);
126+
$poolItem->expiresAfter($item[CacheItem::CAST_PREFIX.'lifetime']);
135127

136128
return $this->pool->$method($poolItem);
137129
}
130+
131+
private function generateItems($items)
132+
{
133+
$f = $this->createCacheItem;
134+
135+
foreach ($items as $key => $item) {
136+
yield $key => $f($key, $item->get(), $item->isHit());
137+
}
138+
}
138139
}

src/Symfony/Component/Cache/CacheItem.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
*/
2020
final class CacheItem implements CacheItemInterface
2121
{
22+
/**
23+
* @internal
24+
*/
25+
const CAST_PREFIX = "\0Symfony\Component\Cache\CacheItem\0";
26+
2227
private $key;
2328
private $value;
2429
private $isHit;

src/Symfony/Component/Cache/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"psr/cache": "~1.0"
2424
},
2525
"require-dev": {
26-
"cache/integration-tests": "^0.6",
26+
"cache/integration-tests": "dev-master",
2727
"doctrine/cache": "~1.6"
2828
},
2929
"autoload": {

0 commit comments

Comments
 (0)
0