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

Lazy loaded entry null is still cached, for a short period #64

Open
cdekker opened this issue Apr 23, 2019 · 1 comment
Open

Lazy loaded entry null is still cached, for a short period #64

cdekker opened this issue Apr 23, 2019 · 1 comment

Comments

@cdekker
Copy link

cdekker commented Apr 23, 2019

I am trying to implement a 'near-cache' for an expensive Database query using ExpiringMap. The following example is a gross simplification, but should describe the gist of it. In the real, more complex implementation the expiration time is different for each entry and there is some more logic associated with each entry which is not relevant for this issue.

ExpiringMap.builder()
	.variableExpiration()
	.expiringEntryLoader((ExpiringEntryLoader<String, DBItem>) id -> {

		DBItem obj = Database.findById(id);

		return (obj != null) ? new ExpiringValue<>(obj, 5, TimeUnit.MINUTES) : null;
	})
	.build();

This works fine for when the item is found in the database. The first time the DB is hit and the item is cached for 5 minutes, while all future calls within that duration only hit the ExpiringMap cache.

However, if the object is not found in the DB, then null is still cached. Even weirder, it seems to be cached for some short default duration that I did not define anywhere (1 minute?). Is there a way to avoid this behavior and prevent a value from being stored in the map? In case of null, I would like each subsequent get call to hit the database again.

@jhalterman
Copy link
Owner

jhalterman commented Apr 26, 2019

Even weirder, it seems to be cached for some short default duration that I did not define anywhere (1 minute?)

This sounds like a bug

Is there a way to avoid this behavior and prevent a value from being stored in the map?

That would change the behavior/contract of ExpiringEntryLoader, but I think it's a fair change that null should be a distinguished return value that causes an entry not to be loaded. Alternative, we could have some other distinguished return value, such as ExpiringValue.NONE that one could return in such cases (while still allowing null).

Happy to take a PR to fix these.

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