Repository navigation
Releases
Releases · nette/caching
Released version 4.0.0
Two new storages, a lock that really prevents cache stampede, and an API in which a mistake in dependencies or invalidation fails loudly instead of quietly leaving stale data in the cache.
✨ New Features
- RedisStorage – a native Redis backend that keeps tags and priorities itself, so it needs no journal, cleans namespaces, and lets only one process generate a missing item while the others wait for it (the lock expires after
$lockTimeout) - Psr16Storage – any PSR-16 cache can now serve as a Nette storage;
PsrCacheAdapterkeeps covering the opposite direction - Dependencies – describe dependencies with a typed object your IDE understands:
new Dependencies(expire: '20 minutes', tags: [...]), or type the generator's parameter asDependencies $dpand write$dp->expire = '20 minutes'; the array withCache::*keys still works - clean() with named arguments –
$cache->clean(tags: ["article/$id"]),priority: 100orall: true - Stronger stampede protection – FileStorage reads the item again once it gets the lock, so a process that waited for another one returns the fresh value instead of generating it a second time; a storage opts in through the new
LockingReaderinterface - MemoryStorage honors
Expire,Sliding,Tags,Priorityand cleaning by namespace, which makes it a realistic stand-in in tests (#85) - SQLiteStorage cleans by namespace and runs in WAL mode, so readers and a writer no longer block each other
- serializeData() and unserializeData() of FileStorage can be overridden to store data in another format (#82)
- PHPStan now attributes exceptions thrown in the callbacks of
load(),bulkLoad()andcall()to their caller (#87)
💥 Breaking Changes
- Requires PHP 8.4, nette/utils 4.1 and, for the
{cache}tag, Latte 3.1 Storage::lock()is gone; a custom storage that should generate a missing item in one process at a time implementsLockingReader::readOrGenerate().Cache::save()with a closure is deprecated, pass the closure toload()as the generator- An unknown key or a value of a wrong type in dependencies or in the conditions of
clean()throws an exception, and so doesclean()without any condition; expired items are removed by$storage->clean([]) clean(all: true)on a cache with a namespace removes only that namespace and the ones derived from it; a cache without a namespace still clears the whole storage. Cleaning byCache::Namespacesincludes the derived namespaces as well- A storage throws
NotSupportedExceptionfor a dependency or condition it cannot honor, such asPriorityin SQLiteStorage or cleaning by namespace in MemcachedStorage PsrCacheAdaptervalidates keys as PSR-16 requires, souser:1and other keys with{}()/\@:are rejected- The interfaces
IStorage,IJournalandIBulkReaderand the service aliasescacheStorageandnette.cacheJournalare removed; the UPPERCASE constants such asCache::EXPIREandCache::start()trigger a deprecation notice
The complete list with migration hints is in docs/upgrading.md.
🐛 Bug Fixes
- MemcachedStorage extends a sliding expiration without storing back an item written in between
- A failed write to Memcached, such as an item over the size limit, triggers a warning (#71)
- FileStorage leaves no empty file behind when a generator fails, and a generator that generates its own item gets an exception instead of waiting for its own lock
⚡ Performance
- The FileStorage constructor collects garbage in batches limited to 20 ms instead of walking the whole cache, so a large cache no longer slows down the request that triggers the cleanup
PsrCacheAdapter::getMultiple()reads all the keys in one bulk request
Released version 3.4.3
✨ New Features
- Ready for PHP 8.6
- SQLiteStorage now cleans up after itself – expired items are removed by probabilistic garbage collection, just like in FileStorage (#83)
🐛 Bug Fixes
- FileStorage: an
Itemsdependency on an item that is being generated at the same moment no longer hangs the process (#54) - FileStorage: cleaning the cache leaves alone files and directories of other tools sharing the cache directory, such as Latte, and copes safely with any foreign file it comes across (#45)
- MemcachedStorage: items with an expiration longer than 30 days are now kept for the intended time
- SQLiteStorage:
bulkRead()works with any number of keys, regardless of the SQLite limit of query parameters
🛡️ Robustness
- PsrCacheAdapter follows PSR-16 more closely: a zero or negative TTL deletes the item, and a
DateIntervalTTL is converted independently of the timezone - Edge cases in storages: a non-positive expiration in MemcachedStorage removes the item, SQLiteJournal keeps priority 0, SQLiteStorage ignores
SlidingwithoutExpirelike the other storages, and SQLite transactions are rolled back on failure
Released version 3.4.2
A housekeeping release focused on code quality: every class and method now carries clearer, more descriptive PHPDoc, type hints got sharper (both native and annotated), and static analysis is now a mandatory part of CI with the official Nette PHPStan rules. No API changes – just a tidier, better-typed codebase.
Released version 3.4.0
- requires PHP 8.1
- support for PHP 8.5
- optimized global function calls
- removed support for Latte 2
Released version 3.3.1
- added PSR-16 adapter (#77)
- support for PHP 8.4
Released version 3.3.0
- Bulk write implementation (#73)
- CacheExtension: accepts complete path (BC break)
- CacheExtension, FileStorage: checks whether directory is absolute
- removed Nette\SmartObject
Released version 3.2.3
Released version 3.2.2
- requires PHP 8.0
- added $dependencies as a Cache::load() 3rd parameter
- Latte: runtime helpers moved to Runtime class
Released version 3.1.4
Released version 3.1.3
- support for Latte 3
- coding style