@Override public Object load(final Object key) { return supplier.get(); }
@Nonnull @Override public V load(@Nonnull ReferenceKey key) { return supplier.get(); } }
@Override public Map loadAll(final Collection keys) { Map<ReferenceKey, V> map = new HashMap<ReferenceKey, V>(); for (Object key : keys) { final V value = supplier.get(); if (value != null) { map.put(ReferenceKey.KEY, value); } } return map; }
/** * Version of {@link org.hamcrest.MatcherAssert#assertThat} that retries for a brief duration before giving up. * This allows reasonable testing of caches with relaxed consistency semantics. * @param actual a supplier that, when evaluated via {@link Supplier#get()}, returns the actual value to be checked. * This supplier <strong>must</strong> be idempotent, as it will be called repeatedly until either * the matcher matches or the timeout is exceeded. * @param matcher a matcher that checks the actual value */ protected static <T> void assertEventuallyThat(Supplier<T> actual, Matcher<? super T> matcher) { final int TIMEOUT_MILLIS = 200; final int SLEEP_MILLIS = 5; try { for (int millis = 0; !matcher.matches(actual.get()) && millis < TIMEOUT_MILLIS; millis += SLEEP_MILLIS) { Thread.sleep(SLEEP_MILLIS); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } assertThat(actual.get(), matcher); }
@Nonnull @Override public V get(final K key, final Supplier<V> supplier) { notNull("key", key); final RequestCacheController.CacheContext cacheContext = getContext(); if (cacheContext == null) { // no cache in context - load it the slow way each time return getNotNull("supplier", key, supplier.get()); } final Map<Object, Object> localMap = cacheContext.getLocalMap(this); final Object cachedValue = localMap.get(key); if (cachedValue != null) { //noinspection unchecked return (V)cachedValue; } final V loadedValue = getNotNull("supplier", key, supplier.get()); localMap.put(key, loadedValue); return loadedValue; }
@Override public Versioned<V> get() { long version = getVersion(); V value = supplier.get(); if (value == null) { throw new CacheException("The Supplier for cached reference '" + getName() + "'returned null. Null values are not supported."); } return new Versioned<V>(value, version); } };
@Test public void testOnSet() throws Exception { Supplier<String> supplier = mock(Supplier.class); when(supplier.get()).thenReturn("SET"); CachedReference<String> reference = factory.getCachedReference("set", supplier, settingsBuilder().build()); CachedReferenceListener listener = mock(CachedReferenceListener.class); reference.addListener(listener, true); reference.get(); ArgumentCaptor<CachedReferenceEvent> captor = ArgumentCaptor.forClass(CachedReferenceEvent.class); verify(listener, timeout(1000)).onSet(captor.capture()); CachedReferenceEvent<String> event = captor.getValue(); assertEquals("SET", event.getValue()); }
@Test public void testOnReset() throws Exception { Supplier<String> supplier = mock(Supplier.class); when(supplier.get()).thenReturn("RESET"); CachedReference<String> reference = factory.getCachedReference("reset", supplier, settingsBuilder().build()); CachedReferenceListener listener = mock(CachedReferenceListener.class); reference.addListener(listener, true); reference.get(); reference.reset(); ArgumentCaptor<CachedReferenceEvent> captor = ArgumentCaptor.forClass(CachedReferenceEvent.class); //With the changes to the delegated memory reset / remove there will be another call on the //listener when this test is run as part of the suite verify(listener, timeout(1000).atLeastOnce()).onReset(captor.capture()); CachedReferenceEvent<String> event = captor.getValue(); assertEquals("RESET", event.getValue()); }
@Test public void testOnEvict() throws Exception { Supplier<String> supplier = mock(Supplier.class); when(supplier.get()).thenReturn("EVICT"); CachedReference<String> reference = factory.getCachedReference("evict", supplier, settingsBuilder().expireAfterAccess(1, TimeUnit.SECONDS).expireAfterWrite(1, TimeUnit.SECONDS).build()); CachedReferenceListener listener = mock(CachedReferenceListener.class); reference.addListener(listener, true); reference.get(); Thread.sleep(EXPIRY_TIMEOUT); reference.get(); ArgumentCaptor<CachedReferenceEvent> captor = ArgumentCaptor.forClass(CachedReferenceEvent.class); verify(listener, timeout(EXPIRY_TIMEOUT).atLeastOnce()).onEvict(captor.capture()); CachedReferenceEvent<String> event = captor.getValue(); assertEquals("EVICT", event.getValue()); }
@Nonnull @SuppressWarnings ("unchecked") @Override public V get() { try { OsgiSafe<V> value = hazelcastMap.get(REFERENCE_KEY); if (value == null) { V newValue = supplier.get(); if (newValue == null) { throw new CacheException("The provided supplier returned null. Null values are not supported."); } value = wrap(newValue); OsgiSafe<V> current = hazelcastMap.putIfAbsent(REFERENCE_KEY, value); return unwrap(MoreObjects.firstNonNull(current, value)); } return unwrap(value); } catch (RuntimeException e) { Throwables.propagateIfInstanceOf(e, CacheException.class); throw new CacheException(e); } }
private V getOrLoad(final K key, final Supplier<? extends V> valueSupplier) { try { OsgiSafe<V> value = map.get(checkNotNull(key, "key")); if (value != null) { return value.getValue(); } else if (valueSupplier == null) { return null; } V newValue = valueSupplier.get(); //noinspection ConstantConditions if (newValue == null) { throw new CacheException("The provided cacheLoader returned null. Null values are not supported."); } value = wrap(newValue); OsgiSafe<V> current = map.putIfAbsent(key, value); return unwrap(MoreObjects.firstNonNull(current, value)); } catch (RuntimeException e) { Throwables.propagateIfInstanceOf(e, CacheException.class); throw new CacheException("Problem retrieving a value from cache " + getName(), e); } }
private Versioned<V> loadAndVersion(final K key, Supplier<? extends V> supplier) { try { // retrieve the current version if it exists and is compatible with the generated value (identical hash), // otherwise generate or increment the tracked version long version = getVersion(key); V value = supplier.get(); //noinspection ConstantConditions if (value == null) { throw new CacheException("The generated value for cache '" + getName() + "' was null for key '" + key + "'. Null values are not supported."); } log.debug("Generated value '{}' for key '{}' in cache with name '{}'", value, key, localCache.getName()); return new Versioned<V>(value, version); } catch (RuntimeException e) { Throwables.propagateIfInstanceOf(e, CacheException.class); throw new CacheException("Error generating a value for key '" + key + "' in cache '" + localCache.getName() + "'", e); } }
return Objects.requireNonNull(valueLoader.get());