Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schedule() is not running exactly after expiry of each entry, it works only for first entry expiry #1622

Closed
nemadev888 opened this issue Apr 1, 2024 · 4 comments

Comments

@nemadev888
Copy link

Hi Team,

I am using below code snippet to create cache manager:

CaffeineCache cache = new CaffeinceCache("poc-cache", Caffeince.newBuilder()
.scheduler(Scheduler.forScheduledExecutorService(new ScheduledTheadpoolExecutor(1)))
.expiryAfterWrite(60, TimeUnit.SECONDS)
.removalListener(new CustomRemovalListener())
.maximumSize(10)
.build())

In my case, I want to achieve below things:

  1. After exactly expiring time of each entry, want to invoke removalListener
  2. In removal Listener, want to reload the value asynchronously in cache for expired key again

Using version: 2.8.0 and Java 8

output of my code:
2024-04-01 **12:55:12.**760 INFO 33588 --- [nio-8080-exec-2] : cache populated with key: 121
2024-04-01 12:55:45.690 INFO 33588 --- [nio-8080-exec-4] : cache populated with key: 122
2024-04-01 12:56:12.778 INFO 33588 --- [onPool-worker-2] : Expiring the key: 121
2024-04-01 12:56:15.561 INFO 33588 --- [nio-8080-exec-8] : cache populated with key: 123
2024-04-01 12:57:39.862 INFO 33588 --- [onPool-worker-4]: Expiring the key: 123
2024-04-01 12:57:39.862 INFO 33588 --- [nPool-worker-13] : Expiring the key: 122

If you see, for first entry, that removal Listener executed by the scheduler at exact expiry time, but for other 2 entries, it didn't.

Please suggest, if I am missing some thing on cache config.

Regards,
Devesh

@ben-manes
Copy link
Owner

Perhaps the ForkJoinPool.commonPool() is flooded so the listener is waiting longer than expected. A lot of times it’s overused for blocking IO even though it’s designed for cpu-bound tasks, often because it’s the default executor for CompletableFuture. You can try setting Caffeine.executor(es) to see if that helps.

@nemadev888
Copy link
Author

nemadev888 commented Apr 1, 2024

Hi Ben,

ExecutorService es = Executors.newFixedThreadPool(10);
Even after using giving Executor in execuor() function, There is no change in the behavior. does removal Listener not run at the exact time of expiry?
I was reading this page: https://stackoverflow.com/questions/68101454/caffeine-combining-both-scheduler-and-executor-service

Where you mentioned that If the next expiration event is in the distant future then the scheduler won't run until then, though calling threads may trigger a maintenance cycle due to their activity on the cache (see #1,2).

@ben-manes
Copy link
Owner

I think you’d need to debug it further or reproduce in a test. For example decorate the scheduled executor to print a message when a task is being run to see if it’s prompt. Then see if something is blocking progress if otherwise correct. It should try to run with a 1s tolerance unless something else is obstructing the maintenance process. It’s also possible that an upgrade might help since you are on a pretty old version.

@ben-manes
Copy link
Owner

Closing due to lack of feedback. If you can provide a sample to that demonstrates this problem, please reopen! I just don't have enough to information to go on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants