I need to check some endpoints in different intervals, so I set up the Caffeine's cache builder .
this.localeWeatherCache = newBuilder().build();
this.currentWeatherCache=newBuilder().expireAfterWrite(Duration.ofHours(3)).build();
this.weatherForecastsCache = newBuilder().expireAfterWrite(Duration.ofHours(12)).build();
In my Service I call those 3 endpoints, in the end I return my object with all details usin Mono.zip().
During my tests, I noticed that climaTempoRepository.findLocaleByCityNameAndState is executed twice and after the currentWeather cache expires it makes another call to locale endpoint, the same happens with weatherForecast, it calls again the locale.
Why it fails? Shouldn't it use cache? Or the way I did is wrong?
Any help or pointers are greatly appreciated! :)
public Mono<Weather> weatherForecastByLocation(Location location) {
Mono<ClimaTempoLocale> locale =
CacheMono.lookup(key ->
Mono.justOrEmpty(localeWeatherCache.getIfPresent(key))
.map(Signal::next), location)
.onCacheMissResume(() -> climaTempoRepository.findLocaleByCityNameAndState(location.city(), location.state()))
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> localeWeatherCache.put(key, value))));
Mono<CurrentWeather> currentWeather =
CacheMono.lookup(key ->
Mono.justOrEmpty(currentWeatherCache.getIfPresent(key))
.map(Signal::next), location)
.onCacheMissResume(() -> locale.flatMap(climaTempoRepository::findCurrentWeatherByLocale)
.subscribeOn(Schedulers.elastic()))
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> currentWeatherCache.put(key, value))));
Mono<WeatherForecasts> weatherForecasts =
CacheMono.lookup(key ->
Mono.justOrEmpty(weatherForecastsCache.getIfPresent(key))
.map(Signal::next), location)
.onCacheMissResume(() -> locale.flatMap(climaTempoRepository::findDailyForecastByLocale)
.subscribeOn(Schedulers.elastic()))
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> weatherForecastsCache.put(key, value))));
return Mono.zip(currentWeather,
weatherForecasts,
(current, forecasts) ->
Weather.buildWith(builder -> {
builder.location = location;
builder.currentWeather = current;
builder.weatherForecasts = forecasts;
}));
}