sorry for the late reply, here are my thoughts on your approach. My thoughts do focus on specific details, although you stated you wanted to avoid details in this thread, but I could not help myself but wanted to answer:
In general, I’m for using PSR-based libraries which let’s us focus on Content Management, and not framework specific implementations like cache backends ;). OTOH our caching framework has proven to be reliable and really stable, but I do miss proper two-level caching mechanisms and the available different “cache frontends” seems strange.
File-based caching by default
Although you’ve run your stats on several machines (dev and prod), I’m not sure about the impact on having file-based caching by default, actually. I also have some NFS-based installations lying around. Especially setting up cache_rootline is a pain on FS by default, I’d say. A classic example I’ve seen in several companies: On each deployment, you flush all caches, and the rootline cache on the first page with 200 links on it needs to be rebuilt, taking a lot of time in an installation with 20K pages. I actually have some special cache warmup scripts running to overcome this issue, which is already needed for DB only already, but I’ve seen really bad FS things, not too long ago (see below). I would need to test this case with FS based caching, try with Blackfire on a new DO server with latest master.
This case hits especially hard when doing content management (BE work which permanently clears cache when changing or moving pages) and FE requests with high traffic at the same time - not takling about distributed systems. I’m sure @liayn has some things to add here.
So, you asked for a real life example. Helmut and me spent several weeks to get rid of the file-based “class loader cache” in TYPO3 6.2.8 which just did a lot of FS work, which is IMHO unnecessary bloating any server. After clearing the system cache, a new FE request took 10secs because of disk IO to create several hundred classes necessary to be used. Of course, we don’t have the class loader cache anymore but going FS first is IMHO not feasible (maybe for cache_pages and cache_pagesection). So, you claim you have the horror stories, I claim that I did and do too. What now?
The main benefits I see of going FS-first would be to put down the work of the DB load and to keep DB dumps small but I’d rather not trade that for performance - by default.
Default Configuration For All Caches
Going further, the “default configuration” approach is exactly the opposite of what I proclaim to most of the projects I do consulting on - think of how big your single cache will be and how much data should go, then see what fits and you have available:
- Use php-apc for small but fast caches (and FS backup when doing custom 2nd level caching), same should go for fluid caches IMHO.
- Use redis for larger caches, think in memory (which is still faster than FS or DB today, as far as I know), and fallback to DB instead, so that’s kind of tricky to handle. However I could see something like “presets” available which could then be applied to the cacheConfigurations.
I’m still unsure how to properly override everything without having side effects. Example:
- A site owner can configure a default configuration in LocalConfiguration.php
- An extension (no TER extension, but a project-specific one) brings an additional cache with it (e.g. “cache_benni”) which is set to be stored in DB
- How would the site owner configure to override this configuration then?
Can we deal with that “by design” to ensure what the desired behaviour is?
Re-reading your Gist document again, I actually worry about performance of “FS first”, and I do have real life examples at hand, either with distributed systems or local file systems running TYPO3 v7 mostly. Maybe we just need a good detection in the install tool what would fit best (“TYPO3’s best guess for your performance”). Also, let’s share the “horror stories” of DB caches at a beer or too
I revised the part of unifying the Cache Frontends, and your approach seems more than logical to me. This is IMHO actually the most confusing part when explaining the current Cache Framework concept. However, we might could go a more drastic way to actually have a “Cache” object which is the replacement for the VariableFrontend, so we could just deprecate the old Frontends and use a new Cache class that replaces them. Would that make sense? So we drop the content of the “frontends” completely (see below for “PSR-6”) - of course with a proper deprecation strategy.
Dropping the getByTag() method does make sense and I’m sure we could find a way to replace this functionality (which only exists for AdminPanel within extGetNumberOfCachedPages()) in a better way - just don’t have a good idea at hand.
Personally, I would not put locking into caching itself - it’s a separate topic. I do understand your use-case but I’ve never seen mixing locking with caching within a library (in 2017). Separation of concern could and should go in the callers code - where it is needed. Especially when writing 500 entries into cache_rootline in one request would make it really slow when having lock/release for each call. I do miss the use-case apart from “Page is being generated” - because we do locking and we could use libraries like https://github.com/symfony/lock.
Questions like “What happens if I hit “lock()” but get a connection timeout? Will it ever be unlocked? What is the state then?” - There would be backends that do not support locking properly (FS-based caching with NFS + locking - enjoy) - or what would the approach be?
PSR-6 vs. whatever implementation we use
Now, I also need to give some clarification on the PSR-6 topic itself, and this is actually crucial and I took that as a misunderstanding for quite some time after reading your docs:
The standard PSR-6 does not support tags, it is NOT intended to do so - http://www.php-fig.org/psr/psr-6/meta/#non-goals everything we’d do with libraries would need tagging support! I did not study the library you chose, PHP-Cache, in depth, you did, and if that does tagging, that is just something else than “let’s use PSR-6 and we can plug in everything” - however, I do see the possibility to use a third party library with tagging support.
PSR-6 is quite complex with CacheItemInterface which are intended to be objects. Basically our “Cache” / “CacheFrontend” object would need to put our existing key/result value into CacheItems and handle that to the CachePools, same goes when retrieving data. The reason why PSR-16 came to life because of that rather complex PSR-6 setup. Nowadays, frameworks offer adapters to both PSR-6 and PSR-16, which sense IMHO. PSR-16 is however closer to our current Caching Framework (no ->commit()) method etc.).
PHP-Cache / Communicators etc
I think I did not fully understand one part - Using the proposed library we’d have “CacheManager calls getCache fetching the CacheFrontend -> converts to CacheItems => calls PSR-6 CachePool (instead of CacheBackend) => calls Communicator (written by the library) or Doctrine Bridge” - is that right?
OK. Now you have my thoughts. Hope some more will chime in and we can find the best solution out there.