Skip to content

Releases

Released version 4.0.0

Choose a tag to compare

@dg dg released this 06 Nov 17:00

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; PsrCacheAdapter keeps 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 as Dependencies $dp and write $dp->expire = '20 minutes'; the array with Cache::* keys still works
  • clean() with named arguments – $cache->clean(tags: ["article/$id"]), priority: 100 or all: 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 LockingReader interface
  • MemoryStorage honors Expire, Sliding, Tags, Priority and 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() and call() 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 implements LockingReader::readOrGenerate(). Cache::save() with a closure is deprecated, pass the closure to load() 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 does clean() 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 by Cache::Namespaces includes the derived namespaces as well
  • A storage throws NotSupportedException for a dependency or condition it cannot honor, such as Priority in SQLiteStorage or cleaning by namespace in MemcachedStorage
  • PsrCacheAdapter validates keys as PSR-16 requires, so user:1 and other keys with {}()/\@: are rejected
  • The interfaces IStorage, IJournal and IBulkReader and the service aliases cacheStorage and nette.cacheJournal are removed; the UPPERCASE constants such as Cache::EXPIRE and Cache::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

Choose a tag to compare

@dg dg released this 27 Oct 18:41

✨ 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 Items dependency 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 DateInterval TTL 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 Sliding without Expire like the other storages, and SQLite transactions are rolled back on failure

Released version 3.4.2

Choose a tag to compare

@dg dg released this 12 May 01:33

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

Choose a tag to compare

@dg dg released this 06 Aug 23:07
  • requires PHP 8.1
  • support for PHP 8.5
  • optimized global function calls
  • removed support for Latte 2

Released version 3.3.1

Choose a tag to compare

@dg dg released this 07 Aug 00:04
  • added PSR-16 adapter (#77)
  • support for PHP 8.4

Released version 3.3.0

Choose a tag to compare

@dg dg released this 10 Mar 22:10
  • 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

Choose a tag to compare

@dg dg released this 02 Nov 23:25
  • support for PHP 8.3

Released version 3.2.2

Choose a tag to compare

@dg dg released this 13 Jan 03:38
  • requires PHP 8.0
  • added $dependencies as a Cache::load() 3rd parameter
  • Latte: runtime helpers moved to Runtime class

Released version 3.1.4

Choose a tag to compare

@dg dg released this 18 Oct 23:26
  • SQLiteJournal: speed up cache writing, prevent database locked error (#66)
  • CacheExtension: used getProviders()
  • Cache: returned NAMESPACE_SEPARATOR back (don't use it, it's internal) #67

Released version 3.1.3

Choose a tag to compare

@dg dg released this 17 May 18:31
  • support for Latte 3
  • coding style