Index: src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java =================================================================== --- src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java (revision 1226846) +++ src/test/java/org/apache/http/impl/client/cache/memcached/TestMemcachedHttpCacheStorage.java (working copy) @@ -35,6 +35,7 @@ import net.spy.memcached.CASResponse; import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClientIF; +import net.spy.memcached.OperationTimeoutException; import org.apache.http.client.cache.HttpCacheEntry; import org.apache.http.client.cache.HttpCacheEntrySerializer; @@ -102,6 +103,22 @@ } @Test + public void testCacheGetThrowsTimeoutException() + throws UnsupportedEncodingException, IOException { + final String url = "foo"; + EasyMock.expect(mockMemcachedClient.get(url)).andThrow( + new OperationTimeoutException("op timeout")); + replayMocks(); + try { + impl.getEntry(url); + fail("IOException not thrown"); + } catch (IOException ex) { + assertTrue(ex instanceof IOException); + } + verifyMocks(); + } + + @Test public void testCacheGetNullEntry() throws IOException { final String url = "foo"; @@ -187,6 +204,44 @@ } @Test + public void testCacheUpdateThrowsTimeoutException() throws IOException, HttpCacheUpdateException { + final String url = "foo"; + final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry(); + final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry(); + + CASValue v = new CASValue(1234, new byte[] {}); + + HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback() { + public HttpCacheEntry update(HttpCacheEntry old) { + assertEquals(existingValue, old); + return updatedValue; + } + }; + + // get existing old entry + EasyMock.expect(mockMemcachedClient.gets(url)).andReturn(v); + EasyMock.expect( + mockSerializer.readFrom(EasyMock.isA(InputStream.class))) + .andReturn(existingValue); + + // update + EasyMock.expect( + mockMemcachedClient.cas(EasyMock.eq(url), EasyMock.eq(v + .getCas()), EasyMock.aryEq(new byte[0]))).andThrow( + new OperationTimeoutException("op timeout")); + mockSerializer.writeTo(EasyMock.same(updatedValue), EasyMock + .isA(OutputStream.class)); + replayMocks(); + try { + impl.updateEntry(url, callback); + fail("IOException not thrown"); + } catch(IOException ex) { + assertTrue(ex instanceof IOException); + } + verifyMocks(); + } + + @Test public void testSingleCacheUpdateRetry() throws IOException, HttpCacheUpdateException { final String url = "foo"; Index: src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.java =================================================================== --- src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.java (revision 1229203) +++ src/main/java/org/apache/http/impl/client/cache/memcached/MemcachedHttpCacheStorage.java (working copy) @@ -36,6 +36,7 @@ import net.spy.memcached.CASValue; import net.spy.memcached.MemcachedClient; import net.spy.memcached.MemcachedClientIF; +import net.spy.memcached.OperationTimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -144,7 +145,11 @@ } public HttpCacheEntry getEntry(String url) throws IOException { - return reconstituteEntry(client.get(url)); + try { + return reconstituteEntry(client.get(url)); + } catch (OperationTimeoutException ex) { + throw new IOException(ex); + } } public void removeEntry(String url) throws IOException { @@ -155,25 +160,28 @@ throws HttpCacheUpdateException, IOException { int numRetries = 0; do { + try { + CASValue v = client.gets(url); + HttpCacheEntry existingEntry = (v == null) ? null + : reconstituteEntry(v.getValue()); + HttpCacheEntry updatedEntry = callback.update(existingEntry); - CASValue v = client.gets(url); - HttpCacheEntry existingEntry = (v == null) ? null - : reconstituteEntry(v.getValue()); - HttpCacheEntry updatedEntry = callback.update(existingEntry); + if (v == null) { + putEntry(url, updatedEntry); + return; - if (v == null) { - putEntry(url, updatedEntry); - return; - - } else { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - serializer.writeTo(updatedEntry, bos); - CASResponse casResult = client.cas(url, v.getCas(), bos.toByteArray()); - if (casResult != CASResponse.OK) { - numRetries++; - } else return; + } else { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + serializer.writeTo(updatedEntry, bos); + CASResponse casResult = client.cas(url, v.getCas(), + bos.toByteArray()); + if (casResult != CASResponse.OK) { + numRetries++; + } else return; + } + } catch (OperationTimeoutException ex) { + throw new IOException(ex); } - } while (numRetries <= maxUpdateRetries); throw new HttpCacheUpdateException("Failed to update");