Do not pollute Cache with failed futures

This commit is contained in:
Jason Tedor 2015-10-13 22:14:13 -04:00
parent 1d0b93f766
commit 2e445d3ede
1 changed files with 12 additions and 2 deletions

View File

@ -340,8 +340,18 @@ public class Cache<K, V> {
Entry<K, V> entry; Entry<K, V> entry;
try { try {
entry = future.get(); entry = future.get();
} catch (InterruptedException e) { } catch (ExecutionException | InterruptedException e) {
throw new ExecutionException(e); // if the future ended exceptionally, we do not want to pollute the cache
// however, we have to take care to ensure that the polluted entry has not already been replaced
try (ReleasableLock ignored = segment.writeLock.acquire()) {
Future<Entry<K, V>> sanity = segment.map.get(key);
try {
sanity.get();
} catch (ExecutionException | InterruptedException gotcha) {
segment.map.remove(key);
}
}
throw (e instanceof ExecutionException) ? (ExecutionException)e : new ExecutionException(e);
} }
if (entry.value == null) { if (entry.value == null) {
throw new ExecutionException(new NullPointerException("loader returned a null value")); throw new ExecutionException(new NullPointerException("loader returned a null value"));