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

Populate front-end cache when hitting a backend #1

Closed
Krinkle opened this issue May 28, 2014 · 4 comments
Closed

Populate front-end cache when hitting a backend #1

Krinkle opened this issue May 28, 2014 · 4 comments

Comments

@Krinkle
Copy link

Krinkle commented May 28, 2014

When e.g. using two backends (MemoryCache and FileSystemCache), in the run time that populated the value, it will be in both backends, and for the remainder of that runtime it will be returned quickly from the memory cache.

In subsequent request it is a cache miss in MemoryCache no matter how many times it goes out and fetches it from disk.

Ideally there'd be a way (or perhaps even always) to (re)populate earlier caches when the multi-cache get() gets a hit somewhere in the loop.

I used to have lots of in-object caches (private members in classes), but love the idea of a multi-cachebackend interface like this. As it allows me to use one simple interface and automatically make use of quick caching of values previously retrieved (and stored) in the current request. Traditionally when something is looked up a lot within the application I'd use an ad-hoc store, but simply getting it from cache always is quite neat and minimalistic, but without this feature it seems a bit risky (if I didn't know better I'd think this is a bug).

@Krinkle
Copy link
Author

Krinkle commented May 28, 2014

While I don't make use of this class, I wrote a similar interface a while back that I recently rewrote to support multiple layers.

In there I added a "harvest" feature that essentially does what my opening post describes is lacking.

Source code:
https://github.com/Krinkle/toollabs-base/blob/c50f421ffc/src/Cache.php#L29-L86

Example / test:
https://github.com/Krinkle/toollabs-base/blob/c50f421ffc/test/unit/suites/CacheTest.php#L51-L73

@c9s
Copy link
Collaborator

c9s commented Jun 10, 2016

Thank you for writing this. It looks like I missed the notification mail from GitHub. I will take the advice from your comments. :)

@Krinkle
Copy link
Author

Krinkle commented Jun 10, 2016

Thanks! There is actually one lacking in my implementation that was fine for my naive personal use case, but may be problematic in a more advanced environment where TTL is relied on. My implementation will effectively renew a value and thus potentially cause it to be cached beyond the original expiration time (since it won't know the ttl in a get() call, and we don't know when the value was first stored). This won't matter in case the front layer is in-process memory. But if the front layer is something else that persistst (e.g. APCu, Memcached, Redis) then it will potentially be put in the front layer a second time and stay there way beyond the expiration of the original value in the backend layer.

At Wikimedia a more advanced version exists (MultiWriteBagOStuff.php) which will only repopulate the front layer in case the caller indicates that the key is verifiable (e.g. the value is deterministic and the key contains a hash of the input or something like that, or, the value contains a flag or property of some kind that the caller can use to verify that it is the correct value). This way will avoid blindly renewing things.

Just something to keep in mind :)

@c9s
Copy link
Collaborator

c9s commented Jun 11, 2016

BTW, This idea was coming from a perl module Cache::Cascade, see https://github.com/karenetheridge/Cache-Cascade

@Krinkle Krinkle closed this as completed Mar 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants