Node Cache: Cache Operations#
This page covers the normal application-facing Cache facade: reads,
writes, tags, deferred items, and source-data invalidation patterns.
Normal cache operations#
NodeCache::create() returns Infocyph\CacheLayer\Cache\Cache. Do not
reach into its SQLite adapter for ordinary application work. Use the facade.
Simple read and write#
$cache->set('product.42', ['id' => 42, 'name' => 'Keyboard'], 300);
$product = $cache->get('product.42');
$missing = $cache->get('does-not-exist', 'fallback');
$cache->delete('product.42');
$cache->clear(); // clears this namespace on this node only
set() accepts an integer TTL, a DateInterval, or null. null
uses no explicit expiry; prefer bounded TTLs for data that can change. A TTL of
zero expires immediately. Valid keys contain only letters, digits, _,
., and -.
Read-through caching with remember()#
Use remember() for the normal cache-aside read path. It reads first, then
uses the configured local lock to prevent many concurrent requests on the same
node from doing the same expensive work.
$product = $cache->remember(
'product.42',
function ($item) use ($repository) {
$item->expiresAfter(300);
return $repository->find(42);
},
tags: ['products', 'product.42'],
);
The lock is node-local. Two different servers may both recompute a missing value; that is expected for Node Cache. Use short, suitable TTLs and make the resolver safe to run more than once.
PSR-6 items and deferred writes#
The facade also acts as a PSR-6 pool. Deferred items are held in memory until
commit() and are then written to SQLite in a batch before APCu is updated.
$first = $cache->getItem('product.42')
->set($product)
->expiresAfter(300);
$second = $cache->getItem('product.43')
->set($otherProduct)
->expiresAfter(300);
$cache->saveDeferred($first);
$cache->saveDeferred($second);
$cache->commit();
For simple batches, use the PSR-16 methods instead:
$cache->setMultiple([
'product.42' => $product,
'product.43' => $otherProduct,
], 300);
$products = $cache->getMultiple(['product.42', 'product.43']);
$cache->deleteMultiple(['product.42', 'product.43']);
saveDeferred() is for batching in one process. It does not survive a
process crash before commit() and is not an asynchronous queue.
Common source-data workflows#
Create or update a record#
After the authoritative database transaction succeeds, either delete the exact key or invalidate the business tag. Avoid writing a speculative database value to cache before its transaction commits.
$database->transaction(function () use ($repository, $input): void {
$repository->updateProduct(42, $input);
});
$cache->delete('product.42');
$cache->invalidateTags(['products', 'category.10']);
The next reader rebuilds entries through remember(). This approach avoids
having cache state become the source of truth.
Delete a record#
Delete the exact record key and any aggregate tags after the source deletion is committed:
$repository->deleteProduct(42);
$cache->delete('product.42');
$cache->invalidateTag('products');
When a direct key and its aggregate/list views may be cached, invalidating both is normal and safe.