Skip to content

CacheMono - onCacheMissResume is being called even if there is a value in the cache #234

@hmble2

Description

@hmble2

Even if the value is present in the cache, onCacheMissResume is fired every time.
Issue is due to otherSupplier.get() in method argument is not deferred and hence called immediately.

	public static <KEY, VALUE> MonoCacheBuilderCacheMiss<KEY, VALUE> lookup(
			Function<KEY, Mono<Signal<? extends VALUE>>> reader, KEY key) {
		return otherSupplier -> writer -> Mono.defer(() ->
				reader.apply(key)
				  .switchIfEmpty(otherSupplier.get()
				                              .materialize()
				                              .flatMap(signal -> writer.apply(key, signal)
				                                                       .then(Mono.just(signal))
				                              )
				  )
				  .dematerialize());
	}

and at,

public static <KEY, VALUE> MonoCacheBuilderMapMiss<VALUE> lookup(Map<KEY, ? super Signal<? extends VALUE>> cacheMap, KEY key) {
    return otherSupplier -> Mono.defer(() ->
            Mono.justOrEmpty(cacheMap.get(key))
                .switchIfEmpty(otherSupplier.get().materialize()
                                .doOnNext(value -> cacheMap.put(key, value)))
                .dematerialize()
    );
}

This can be fixed by adding Mono.defer to otherSupplier.get in all places having onCacheMissResume callback e.g.

public static <KEY, VALUE> MonoCacheBuilderCacheMiss<KEY, VALUE> lookup(
		Function<KEY, Mono<Signal<? extends VALUE>>> reader, KEY key) {
	return otherSupplier -> writer -> Mono.defer(() ->
			reader.apply(key)
			  .switchIfEmpty(Mono.defer(()->otherSupplier.get()
			                              .materialize()
			                              .flatMap(signal -> writer.apply(key, signal)
			                                                       .then(Mono.just(signal))
			                              ))
			  )
			  .dematerialize());
}

Workaround: Until the issue is fixed, callback can add a defer to resolve the issue:
.onCacheMissResume(() -> Mono.defer(() -> createExpensiveGraph(key)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    ❓need-triageThis issue needs triage, hasn't been looked at by a team member yet

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions