@@ -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,33 @@ 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- $ ids [$ key ] = $ id ;
150- }
140+ $ ids [$ key ] = $ this ->getId ($ key );
151141 }
152142
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 ;
143+ return $ this ->generateItems ($ ids );
161144 }
162145
163146 /**
164147 * {@inheritdoc}
165148 */
166149 public function hasItem ($ key )
167150 {
168- if ($ this ->deferred ) {
169- $ this ->commit ();
151+ $ id = $ this ->getId ($ key );
152+
153+ if (isset ($ this ->deferred [$ key ])) {
154+ $ item = (array ) $ this ->deferred [$ key ];
155+ $ ok = $ this ->doSave (array ($ item [CacheItem::CAST_PREFIX .'key ' ] => $ item [CacheItem::CAST_PREFIX .'value ' ]), $ item [CacheItem::CAST_PREFIX .'lifetime ' ]);
156+ unset($ this ->deferred [$ key ]);
157+
158+ if (true === $ ok || array () === $ ok ) {
159+ return true ;
160+ }
170161 }
171162
172- return $ this ->doHave ($ this -> getId ( $ key ) );
163+ return $ this ->doHave ($ id );
173164 }
174165
175166 /**
@@ -179,7 +170,7 @@ public function clear()
179170 {
180171 $ this ->deferred = array ();
181172
182- return $ this ->doClear ();
173+ return $ this ->doClear ($ this -> namespace );
183174 }
184175
185176 /**
@@ -198,7 +189,7 @@ public function deleteItems(array $keys)
198189 $ ids = array ();
199190
200191 foreach ($ keys as $ key ) {
201- $ ids [] = $ this ->getId ($ key );
192+ $ ids [$ key ] = $ this ->getId ($ key );
202193 unset($ this ->deferred [$ key ]);
203194 }
204195
@@ -214,10 +205,12 @@ public function save(CacheItemInterface $item)
214205 return false ;
215206 }
216207 $ key = $ item ->getKey ();
208+ if ($ this ->deferred ) {
209+ $ this ->commit ();
210+ }
217211 $ this ->deferred [$ key ] = $ item ;
218- $ this ->commit ();
219212
220- return ! isset ( $ this ->deferred [ $ key ] );
213+ return $ this ->commit ( );
221214 }
222215
223216 /**
@@ -230,10 +223,7 @@ public function saveDeferred(CacheItemInterface $item)
230223 }
231224 try {
232225 $ item = clone $ item ;
233- } catch (\Error $ e ) {
234226 } catch (\Exception $ e ) {
235- }
236- if (isset ($ e )) {
237227 @trigger_error ($ e ->__toString ());
238228
239229 return false ;
@@ -250,7 +240,6 @@ public function commit()
250240 {
251241 $ f = $ this ->mergeByLifetime ;
252242 $ ko = array ();
253- $ namespaceLen = strlen ($ this ->namespace );
254243
255244 foreach ($ f ($ this ->deferred , $ this ->namespace ) as $ lifetime => $ values ) {
256245 if (true === $ ok = $ this ->doSave ($ values , $ lifetime )) {
@@ -259,13 +248,22 @@ public function commit()
259248 if (false === $ ok ) {
260249 $ ok = array_keys ($ values );
261250 }
262- foreach ($ ok as $ failedId ) {
263- $ key = substr ($ failedId , $ namespaceLen );
264- $ ko [$ key ] = $ this ->deferred [$ key ];
251+ foreach ($ ok as $ id ) {
252+ $ ko [$ lifetime ][] = array ($ id => $ values [$ id ]);
253+ }
254+ }
255+
256+ $ this ->deferred = array ();
257+ $ ok = true ;
258+
259+ // When bulk-save failed, retry each item individually
260+ foreach ($ ko as $ lifetime => $ values ) {
261+ foreach ($ values as $ v ) {
262+ $ ok = in_array ($ this ->doSave ($ v , $ lifetime ), array (true , array ()), true ) && $ ok ;
265263 }
266264 }
267265
268- return ! $ this -> deferred = $ ko ;
266+ return $ ok ;
269267 }
270268
271269 public function __destruct ()
@@ -289,4 +287,19 @@ private function getId($key)
289287
290288 return $ this ->namespace .$ key ;
291289 }
290+
291+ private function generateItems ($ ids )
292+ {
293+ $ f = $ this ->createCacheItem ;
294+ $ keys = array_flip ($ ids );
295+
296+ foreach ($ this ->doFetch ($ ids ) as $ id => $ value ) {
297+ yield $ keys [$ id ] => $ f ($ keys [$ id ], $ value , true );
298+ unset($ keys [$ id ]);
299+ }
300+
301+ foreach ($ keys as $ key ) {
302+ yield $ key => $ f ($ key , null , false );
303+ }
304+ }
292305}
0 commit comments