Search code examples
javareactive-programmingspring-data-redisspring-reactive

Unable to load value from Redis alone even if value is present


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?


Solution

  • 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.