Невозможно загрузить значение только из Redis, даже если оно присутствует - PullRequest
0 голосов
/ 05 марта 2020

Я использую Reactive Redis, где я пытаюсь использовать Redis в качестве кэша для базы данных. Я проверяю, присутствует ли значение в кеше или нет? Если он присутствует, вернуть его, в противном случае запросить базу данных, если возвращается результат; сохраните результат в кэш и верните его.

Однако, даже если значение присутствует в Redis, он все еще запрашивает базу данных.

public Mono<User> getUser(String email) {
    return reactiveRedisOperation.opsForValue().get("tango").switchIfEmpty(
        // Always getting into this block (for breakpoint) :(
        queryDatabase().flatMap(it -> {
            reactiveRedisOperation.opsForValue().set("tango", it, Duration.ofSeconds(3600)).then(Mono.just(it)); 
        })
    );
}

private Mono<User> queryDatabase() {
    return Mono.just(new User(2L,"test","test","test","test","test",true,"test","test","test"));
}

Но вызов всегда попадает в базу данных, даже если значение присутствует в Redis. Что я тут не так делаю?

1 Ответ

0 голосов
/ 06 марта 2020

Основываясь на этот ответ Вы можете попробовать с Mono.defer:

public Mono<User> getUser(String email) {
    return reactiveRedisOperation.opsForValue().get("tango").switchIfEmpty(Mono.defer(() -> {
        // Always getting into this block (for breakpoint) :(
        queryDatabase().flatMap(it -> {
            reactiveRedisOperation.opsForValue().set("tango", it, Duration.ofSeconds(3600)).then(Mono.just(it)); 
        })})
    );
}

ОБНОВЛЕНИЕ:

У меня нет большого опыта работы с Mono. Ответ, который я указал, объясняет это:

... вычисление уже было запущено в тот момент, когда мы начинаем составлять наши Mono типы. Чтобы предотвратить нежелательные вычисления, мы можем заключить наше будущее в отложенную оценку:

... захвачен у ленивого поставщика и запланирован к выполнению только тогда, когда он будет запрошен.

...