Skip to content
Bluetape4k docs1.11

Memoizers and same-key work sharing

Latest stable Based on Bluetape4k release 1.11.0

Redisson memoizers store completed values in RMap. A ConcurrentHashMap coordinates in-flight evaluation inside each JVM. Sixteen coroutines in one process can share one evaluation, but two JVMs can still evaluate the same first miss independently.

val squares = redissonClient
.getMap<Int, Int>("memoizer:squares", IntegerCodec())
.suspendMemoizer { key -> expensiveSquare(key) }
val value = squares(7)

This is not a distributed lock. Use locking, fencing, and idempotency when evaluation must happen only once across the cluster.

APIEvaluatorUse it for
memoizer(T) -> RCPU work or an already-blocking call path
asyncMemoizerCompletionStage<R>Java future-based services
suspendMemoizersuspend (T) -> RCoroutine services

All three use putIfAbsent to handle Redis races. Sync and suspend variants return the stored winner. The 1.11.0 async path completes with its evaluated value even if another process won the Redis putIfAbsent, so cross-process callers can temporarily observe different return values.

Evaluator failure completes the promise/deferred exceptionally and removes the in-flight entry. A later call starts a fresh evaluation. The suspend variant also preserves CancellationException and does not store it as a successful value.

Cancelling one waiting coroutine does not automatically cancel the shared deferred. Cancelling the owner evaluation removes the entry and lets the next call retry.

Sync and suspend clear() remove Redis values. Async clear() also clears local in-flight entries. Concurrent clear and evaluation can allow a completing operation to write again or a new caller to start duplicate work. Coordinate operational clears or use generation-based names.

Memoizers belong around repeatable reads and calculations, not payments or message delivery that cannot safely run twice.