EVCacheImpl extends AbstractValueAdaptingCache implements EVCache { @SuppressWarnings("unchecked") @Override public <T> T get(final Object key, final Callable<T> valueLoader) { final String candidateKey = toEVCacheKey(key); final Lock lock = locks.get(candidateKey); lock.lock(); try { final Object cached = doGet(candidateKey); if (nonNull(cached)) { return (T) fromStoreValue(cached); } final T value = valueLoader.call(); doSet(candidateKey, value); return (T) fromStoreValue(value); } catch (final Exception ex) { throw new ValueRetrievalException(key, valueLoader, ex); } finally { lock.unlock(); } } EVCacheImpl(final String name,
                       final com.netflix.evcache.EVCache cache,
                       final boolean allowNullValues,
                       final int striped,
                       final boolean deleteWhitespaceKey); @Override String getName(); @Override com.netflix.evcache.EVCache getNativeCache(); @SuppressWarnings("unchecked") @Override T get(final Object key, final Callable<T> valueLoader); @Override void put(final Object key, final Object value); @Override ValueWrapper putIfAbsent(final Object key, final Object value); @Override void evict(final Object key); @Override void clear();  }
@Test void should_be_not_set_when_callable_key_is_exists() throws EVCacheException { doReturn(1).when(source).get("1"); assertThat(cache.get(1, callable)).isEqualTo(1); verify(source, never()).set(any(), any()); }
@Test void should_be_set_when_callable_key_is_not_exists() throws Exception { doReturn(null).when(source).get("1"); doReturn(2).when(callable).call(); assertThat(cache.get(1, callable)).isEqualTo(2); verify(source).set("1", 2); }
@Test void should_be_locked_when_callable_key_is_same() throws Exception { doAnswer(new AnswersWithDelay(100, new Returns(1))) .doReturn(1).when(source).get("1"); final StopWatch stopWatch = new StopWatch(); Executors.newFixedThreadPool(1).submit(() -> cache.get(1, callable)); stopWatch.start(); assertThat(cache.get(1, callable)).isEqualTo(1); stopWatch.stop(); assertThat(stopWatch.getTotalTimeMillis()).isGreaterThanOrEqualTo(100); }
@Test void should_be_not_locked_when_callable_key_is_not_same() throws Exception { doAnswer(new AnswersWithDelay(100, new Returns(1))).when(source).get("1"); doReturn(2).when(source).get("2"); doReturn(1).when(callable).call(); Executors.newFixedThreadPool(1).submit(() -> cache.get(1, callable)); assertTimeoutPreemptively(ofMillis(20), () -> cache.get(2, callable)); }
@Test void should_be_thrown_ValueRetrievalException_when_callable_throw_Exception() throws Exception { doReturn(null).when(source).get("1"); doThrow(RuntimeException.class).when(callable).call(); assertThatThrownBy(() -> cache.get(1, callable)).isExactlyInstanceOf(Cache.ValueRetrievalException.class); verify(source, never()).set(any(), any()); }