-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Stale data when using Expiry #298
Comments
Thanks. I've been meaning to switch reads to use a compare-and-swap to update the timestamp, but thought it was a benign race so it was in the backlog. I hadn't thought of this case, obviously. Do you think you can write a test case to demonstrate the race? I'm hoping to make a release this weekend when I merge the |
I can't reproduce without pausing thread, a little hard to write test case. |
Oh, take a look at Awaitility which is really handy for these cases. For example, caffeine/caffeine/src/test/java/com/github/benmanes/caffeine/cache/AsyncCacheTest.java Lines 202 to 218 in 1c71c67
but I can also give it a shot when I get free over the weekend. Its a 3 day'r in the U.S. so I should be able to find the time. |
I see. I tried it but looks like problem is Completable just finish but before calling BoundedLocalCache#replace, LocalAsyncLoadingCache#get -> BoundedLocalCache#computeIfAbsent need to check |
okay, thanks. I think this is an easy fix if I understand it correctly, as I've been meaning to get around to making the update on read stricter. Since you found its not easily testable, we can try testing using a thrashing approach, like the MultiThreadedTest does. |
I have a possible fix, but I need to manually verify like you did to see it fail and (maybe) succeed. Then devise if I can get a test case by thrashing it with threads until it breaks. Hopefully have this fixed and released over the weekend. |
I wrote a test, got it to fail, and verified that my change passes it. This was using Technically I shouldn't call I'll take another crack at the test, but otherwise I'm close enough to promise a release over the weekend. |
Thanks, didn't aware my speculation can replay like the test case. 🙇 |
Released 2.7 |
Hi, just wanna give the result, seems the problem is solved. Thanks. |
Great! Thank you for investigating and reporting the bug. |
Recently we start to use Expiry but found some data keep in memory even it exceeds our setting.
After dump we saw stale data all has write time near 150 years later. And after checking source, I think it's from Async.MAXIMUM_EXPIRY.
Below is my sample code.
I think there is a possibility that LocalAsyncLoadingCache#get -> BoundedLocalCache#computeIfAbsent may have race condition with create/update.


If there is a read operation and stop at
isComputingAsync
until task thread finished(but keep it stop at BoundedLocalCache#replace).and
Read thread may enter the block with long duration and make expireAfterRead return MAXIMUM_EXPIRY, so setVariableTime may write
now+MAXIMUM_EXPIRY
.The text was updated successfully, but these errors were encountered: