/* * * Copyright 2016 Robert Winkler * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package io.github.resilience4j.cache; import io.github.resilience4j.cache.event.CacheEvent; import io.github.resilience4j.cache.internal.CacheContext; import io.reactivex.Flowable; import io.vavr.CheckedFunction0; import io.vavr.CheckedFunction1; import java.util.Objects; import java.util.concurrent.Callable; import java.util.function.Function; import java.util.function.Supplier; public interface Cache<K, V> { /** * @return the cache name */ String getName(); /** * Returns the Metrics of this Cache. * * @return the Metrics of this Cache */ Metrics getMetrics(); /** * If the key is not already associated with a cached value, attempts to compute its value using the * given supplier and puts it into the cache. Otherwise it returns the cached value. * If the function itself throws an (unchecked) exception, the exception is rethrown. * * @param key key with which the specified value is to be associated * @param supplier value to be associated with the specified key * * @return cached value */ V computeIfAbsent(K key, CheckedFunction0<V> supplier); /** * Returns a reactive stream of CacheEvents. * * @return a reactive stream of CacheEvents */ Flowable<CacheEvent> getEventStream(); /** * Creates a Retry with default configuration. * * @param cache the wrapped JCache instance * @param <K> the type of key * @param <V> the type of value * @return a Cache */ static <K,V> Cache<K,V> of(javax.cache.Cache<K, V> cache){ Objects.requireNonNull(cache, "Cache must not be null"); return new CacheContext<>(cache); } /** * Creates a functions which returns a value from a cache, if it exists. * Otherwise it calls the Supplier. * * @param cache the Cache * @param supplier the original Supplier * @param <K> the type of key * @param <R> the type of value * @return a supplier which is secured by a CircuitBreaker. */ static <K, R> CheckedFunction1<K, R> decorateCheckedSupplier(Cache<K, R> cache, CheckedFunction0<R> supplier){ return (K cacheKey) -> cache.computeIfAbsent(cacheKey, supplier); } /** * Creates a functions which returns a value from a cache, if it exists. * Otherwise it calls the Supplier. * * @param cache the Cache * @param supplier the original Supplier * @param <K> the type of key * @param <R> the type of value * @return a supplier which is secured by a CircuitBreaker. */ static <K, R> Function<K, R> decorateSupplier(Cache<K, R> cache, Supplier<R> supplier){ return (K cacheKey) -> cache.computeIfAbsent(cacheKey, supplier::get); } /** * Creates a functions which returns a value from a cache, if it exists. * Otherwise it calls the Callable. * * @param cache the Cache * @param callable the original Callable * @param <K> the type of key * @param <R> the type of value * @return a supplier which is secured by a CircuitBreaker. */ static <K, R> CheckedFunction1<K, R> decorateCallable(Cache<K, R> cache, Callable<R> callable){ return (K cacheKey) -> cache.computeIfAbsent(cacheKey, callable::call); } interface Metrics { /** * Returns the current number of cache hits * * @return the current number of cache hits */ long getNumberOfCacheHits(); /** * Returns the current number of cache misses. * * @return the current number of cache misses */ long getNumberOfCacheMisses(); } }