0

I am using Reactive Redis where I am trying to use Redis as cache for database. I am checking if value is present in the cache or not? If it is present then return it otherwise query database if result comes back; store the result cache it and return it.

However, even if value is present in Redis it is still querying the database all the time.

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"));
}

But call is always hitting the database even if value is present in Redis. What am I doing wrong here?

nicholasnet
  • 2,117
  • 2
  • 24
  • 46

1 Answers1

1

Base on this answer you can try with 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)); 
        })})
    );
}

UPDATE:

I don't have much experience with Mono. The answer that I pointed explain it:

... computation was already triggered at the point when we start composing our Mono types. To prevent unwanted computations we can wrap our future into a defered evaluation:

... is trapped in a lazy supplier and is scheduled for execution only when it will be requested.

Community
  • 1
  • 1
lczapski
  • 4,026
  • 3
  • 16
  • 32
  • Unfortunately that did not work either. It is still querying DB even if value is present in Redis. – nicholasnet Mar 06 '20 at 12:10
  • @nicholasnet Update: new approach – lczapski Mar 06 '20 at 12:32
  • I have tried that one too and it was not working. But now I try yours and it is working. Since I have tried so many thing I have lost track of it. But your given solution is working ... so I am good. Thank you very much for your help. But out of curiosity why we need `Mono.defer()` here? – nicholasnet Mar 06 '20 at 15:10
  • @nicholasnet I added update, but explanation is in the answer the I pointed – lczapski Mar 06 '20 at 19:11
  • yeah I noticed that later. I read the link it was good thank you very much for sharing it. – nicholasnet Mar 06 '20 at 19:12