Biscuit128
Biscuit128

Reputation: 5408

How to specify Expiry in Caffeine Cache but only for most recent instance of a given key / value mapping

I have a Caffeine Cache of String id and LocalDateTime (when record was inserted)

I am trying to follow the principle of implementing expiry interface in order to manage expiry times

A code snippet i took from stackoverflow is below

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .expireAfter(new Expiry<Key, Graph>() {
      public long expireAfterCreate(Key key, Graph graph, long currentTime) {
        return 1000;
      }
      public long expireAfterUpdate(Key key, Graph graph, 
          long currentTime, long currentDuration) {
        return 1000;
      }
      public long expireAfterRead(Key key, Graph graph,
          long currentTime, long currentDuration) {
        return currentDuration;
      }
    })
    .build(key -> createExpensiveGraph(key));

What I am struggling to understand is; lets say I put a key in the map, of "A" and a LocalDateTime.now() - it will expire after one second, but assuming i keep repopulating the map with LocalDateTime.now() for key A then I would like the timer to be reset

So in theory, if I infinitely called cache.put("A", LocalDateTime.now()) then I would never get an expiry notification

The actual problem I am trying to solve is, we get an initial update for some keys, and every n number of seconds they should update - hence re adding them to my cache. I don't want the initial insert to trigger the expiry, only the most recent insert for a given key if it exceeds the imposed time constraint

I hope the above makes sense - it is quite difficult to explain

Sample test code -

final Cache<String, LocalDateTime> cache = Caffeine.newBuilder()
        .executor(Runnable::run)
        .ticker(ticker::read)
        .removalListener((key, value, cause) -> {
            if (cause.wasEvicted()) {
                System.out.printf("key=%s, value=%s", key, value);
            }
        })
        .expireAfterWrite(1, TimeUnit.SECONDS)
        .weakKeys()
        .weakValues()
        .build();

Example 2

public class Main implements Runnable{

    final Cache<String, LocalDateTime> cache = Caffeine.newBuilder()
            .executor(Runnable::run)
            .scheduler(createScheduler())
            .removalListener((key, value, cause) -> {
                if (cause == RemovalCause.EXPIRED) {
                    System.out.printf("key=%s, value=%s", key, value);
                }
            })
            .weakKeys()
            .weakValues()
            .expireAfterWrite(10, TimeUnit.SECONDS)
            .build();

    private Scheduler createScheduler() {
        return forScheduledExecutorService(newSingleThreadScheduledExecutor());
    }


    LocalDateTime create(String k) {
        return LocalDateTime.now();
    }

    public void add(String a) {
        cache.put(a, LocalDateTime.now());
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new Main());
        thread.start();
    }

    @Override
    public void run() {
        add("a");
        add("b");
        for(int i = 0; i < 100; i++) {
            System.out.println("adding a" + i);
            add("a");
            try {
                Thread.sleep(900);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Upvotes: 0

Views: 986

Answers (0)

Related Questions