Skip to content

Instantly share code, notes, and snippets.

@abhi2495
Last active July 19, 2020 20:32
Show Gist options
  • Save abhi2495/fd91ff027829ba7e04a770835c0e84d1 to your computer and use it in GitHub Desktop.
Save abhi2495/fd91ff027829ba7e04a770835c0e84d1 to your computer and use it in GitHub Desktop.
/*
##################################################################################
##################################################################################
######### IF YOU FOUND THIS GIST USEFUL, PLEASE LEAVE A STAR. THANKS. ############
##################################################################################
##################################################################################
*/
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CacheConfiguration {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager("myCache");
cacheManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterAccess(Duration.ofHours(1)));
return cacheManager;
}
}

A "reactive" example of in-memory caching of information using CacheMono

In this example, I have created a service which returns the id of a tenant for a given alias either from cache or (if not found) calls a REST API to fetch and stores it in the cache.

@Service
public class TenantService {
private final WebClient webClient;
private final CacheManager cacheManager;
public TenantService(WebClient webClient, CacheManager cacheManager) {
this.webClient = webClient;
this.cacheManager = cacheManager;
}
public Mono<String> getTenantByAlias(String tenantAlias) {
CacheMono.MonoCacheBuilderCacheMiss<String, String> cacheBuilderCacheMiss =
CacheMono.lookup(key -> {
Cache tenantCache = getTenantCache();
Cache.ValueWrapper valueWrapper = tenantCache.get(key);
if (valueWrapper != null) {
System.out.println("Tenant found in cache: " + tenantAlias);
return Mono.just((String) ((Signal) valueWrapper.get()).get()).map(Signal::next);
} else {
System.out.println("Calling tenant service to get tenant id for alias: " + tenantAlias);
return Mono.empty();
}
}, tenantAlias);
CacheMono.MonoCacheBuilderCacheWriter<String, String> cacheBuilderCacheWriter =
cacheBuilderCacheMiss.onCacheMissResume(() -> makeRestCall(tenantAlias));
return cacheBuilderCacheWriter.andWriteWith((key, value) -> Mono.fromRunnable(() -> {
if (!value.isOnError()) {
Cache tenantCache = getTenantCache();
tenantCache.put(key, value);
}
}));
}
private Cache getTenantCache() {
Cache tenantCache = cacheManager.getCache("myCache");
if (tenantCache == null) {
throw new RuntimeException("No such cache found in cache config. Recheck configuration.");
}
return tenantCache;
}
private Mono<String> makeRestCall(String tenantAlias) {
return webClient.get()
.uri(...)
.retrieve()
....
....
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment