Skip to content

'Synchronous listener' isn't synchronous on expirations? #195

@aukevanleeuwen

Description

@aukevanleeuwen

Hello,

I wanted to leverage caffeine in a scenario as follows:

image

Component A puts something on a request queue and stores the request in a (Caffeine) cache as well. When Component B is answering by means of putting something on a response queue the original request is retrieved from the cache and processed further.

However I also have the idea of a timeout on the amount of time waiting for a response. I've tried to implement that as follows:

Creating a cache in Component A as follows:

    this.requestCache = Caffeine.newBuilder()
            .expireAfterWrite(timeoutInMs, TimeUnit.MILLISECONDS)
            .writer(new CompleteExceptionallyOnExpirationWriter())
            .build();
    public class CompleteExceptionallyOnExpirationWriter implements CacheWriter<String, CompletableFuture<PaymentResult>> {

        // <snip>

        @Override
        public void delete(String key, CompletableFuture<PaymentResult> value, RemovalCause cause) {
            if (cause != RemovalCause.EXPLICIT) {
                log.warn("Didn't receive a response on the topic {} within {}ms for payment {}.", topic, timeoutInMs, key);
                value.completeExceptionally(new TimeoutException("Didn't get a response within " + timeoutInMs + "ms."));
            }
        }
    }

I started out by implementing a RemovalListener, but soon noticed that this was an asynchronous process but I also read that a synchronous 'listener' was possible using a CacheWriter.

When the operation must be performed synchronously with the removal, use CacheWriter instead.

However this still doesn't seem to working as I expect. The behaviour that I see now is as follows:

  1. Request 1 arrives and is put in the cache
  2. After 'timeout' nothing happens
  3. Some time later Request 2 arrives and is put in the cache
  4. The moment (3) happens the CacheWriter.delete() of request 1 is triggered.

Now I start out with a rather slow moving cache, so I can't rely on the fact that the cache is always busy enough to trigger something on the 'previous' request timeout.

Is this expected behaviour? It seems kind of odd to me, but I don't see anything wrong with what I'm doing.

Regards,

Auke

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions