monkeyscloud / monkeyslegion-cache
High-performance cache package for MonkeysLegion Framework with multiple drivers, atomic locks, encrypted serialization, and tiered caching
Package info
github.com/MonkeysCloud/MonkeysLegion-Cache
pkg:composer/monkeyscloud/monkeyslegion-cache
Requires
- php: ^8.4
- psr/log: ^3.0
- psr/simple-cache: ^3.0
Requires (Dev)
- phpunit/phpunit: ^11.0
Suggests
- ext-igbinary: For igbinary serialization (30-50% smaller payloads)
- ext-memcached: Required to use Memcached cache driver
- ext-redis: Required to use Redis cache driver and distributed locks
- ext-sodium: Required for encrypted cache serialization (GDPR/PCI)
- monkeyscloud/monkeyslegion-mlc: For .mlc configuration file support with environment variables
This package is auto-updated.
Last update: 2026-04-12 04:31:15 UTC
README
High-performance, attribute-driven cache package for PHP 8.4+ with multiple drivers, atomic locks, encrypted serialization, tiered caching, and stampede protection.
Installation
composer require monkeyscloud/monkeyslegion-cache:^2.0
Features
| Feature | Description |
|---|---|
| 6 Drivers | Array, File, Redis, Memcached, Null, Chain (L1/L2) |
| Pluggable Serializers | PHP, JSON, igbinary, Encrypted (libsodium) |
| Atomic Locks | ArrayLock, FileLock, RedisLock |
| Tag-Based Invalidation | O(1) version-based tag invalidation |
| Stampede Protection | flexible() with probabilistic early expiration |
| Typed Getters | integer(), boolean(), float(), string(), array() |
| TTL Extension | touch() — extend TTL without re-reading value |
| Cache Events | Hit, Miss, Write, Delete — readonly event VOs |
| PSR-16 Compliant | Full Psr\SimpleCache\CacheInterface conformance |
| PHP 8.4 Native | Property hooks, asymmetric visibility, backed enums |
Quick Start
use MonkeysLegion\Cache\CacheManager; $manager = new CacheManager([ 'default' => 'file', 'stores' => [ 'file' => [ 'driver' => 'file', 'path' => __DIR__ . '/cache', ], 'memory' => [ 'driver' => 'array', ], 'redis' => [ 'driver' => 'redis', 'host' => '127.0.0.1', 'port' => 6379, 'prefix' => 'myapp', ], ], ]); $cache = $manager->store(); // Default (file) $redis = $manager->store('redis'); // Named store // Basic operations $cache->set('user.1', $userData, ttl: 3600); $user = $cache->get('user.1'); $cache->delete('user.1');
Typed Getters
No more manual casting:
$count = $cache->integer('page.views'); // int $flag = $cache->boolean('feature.active'); // bool $rate = $cache->float('exchange.rate'); // float $name = $cache->string('user.name'); // string $ids = $cache->array('active.users'); // array
Remember & Stampede Protection
// Cache-aside pattern $users = $cache->remember('users.active', 3600, function () { return $db->query('SELECT * FROM users WHERE active = 1'); }); // Stale-while-revalidate (prevents cache stampede) $data = $cache->flexible( key: 'api.results', ttl: [300, 3600], // [stale_window, fresh_ttl] callback: fn() => $api->fetchExpensiveData(), beta: 1.5, // Higher = more aggressive early refresh );
Tags
O(1) tag invalidation using version-based namespacing:
// Scoped writes $cache->tags(['products', 'electronics'])->set('product.42', $laptop); $cache->tags(['products', 'clothing'])->set('product.99', $shirt); // Mass invalidation — O(1), no key scanning $cache->tags(['electronics'])->flush();
Atomic Locks
Prevent race conditions with distributed locks:
$lock = $cache->lock('deploy', seconds: 30); // Block-scoped (auto-release) $result = $lock->get(function () { return deployApplication(); }, ttl: 30); // Manual acquire/release if ($lock->acquire()) { try { criticalSection(); } finally { $lock->release(); } } // Block with timeout $lock->block(seconds: 10, callback: function () { return processOrder(); });
Lock Backends
| Lock | Use Case |
|---|---|
ArrayLock |
Testing, single-process |
FileLock |
Single-server production |
RedisLock |
Multi-server distributed (Lua-based atomic release) |
Chain Store (L1/L2 Tiered Caching)
$manager = new CacheManager([ 'default' => 'tiered', 'stores' => [ 'l1' => ['driver' => 'array'], // Fast, in-process 'l2' => ['driver' => 'redis', ...], // Shared, durable 'tiered' => ['driver' => 'chain', 'stores' => ['l1', 'l2']], ], ]); $cache = $manager->store(); // ChainStore $cache->get('key'); // L1 miss → L2 hit → promoted to L1
Encrypted Serialization
Transparent at-rest encryption for GDPR/PCI compliance:
$manager = new CacheManager([ 'encrypt_key' => env('CACHE_ENCRYPT_KEY'), // 32+ bytes 'stores' => [ 'secure' => [ 'driver' => 'redis', 'encrypt' => true, // Wrap with sodium_crypto_secretbox 'serializer' => 'json', // Encrypt JSON payloads ], ], ]);
TTL Extension (touch)
Extend cache TTL without re-reading the value (single round-trip on Redis):
// Extend session expiry $cache->touch('session.abc123', ttl: 1800);
Cache Events
Readonly event value objects for telemetry/debugging:
use MonkeysLegion\Cache\Event\CacheEvent; use MonkeysLegion\Cache\Event\CacheEventType; $event = new CacheEvent( type: CacheEventType::Hit, key: 'user.1', store: 'redis', duration: 0.35, ); echo $event->summary; // [redis] hit: user.1 (0.35μs)
CacheEntry Value Object
Introspect cached data with computed properties:
use MonkeysLegion\Cache\CacheEntry; $entry = new CacheEntry( value: $data, expiresAt: time() + 3600, tags: ['user', 'premium'], ); $entry->isExpired; // false (property hook) $entry->remainingTtl; // ~3600 (property hook) $entry->age; // 0 (property hook) $entry->shouldRefresh(beta: 1.5); // probabilistic early refresh
Cache Stats
$stats = $cache->getStats(); echo $stats->hits; // 1423 echo $stats->hitRate; // 0.95 (property hook) echo $stats->memoryFormatted; // "2.45 MB" (property hook)
Pluggable Serializers
| Serializer | Best For |
|---|---|
PhpSerializer |
Default, supports all PHP types |
JsonSerializer |
Scalars/arrays, zero code execution risk |
IgbinarySerializer |
30-50% smaller payloads (requires ext-igbinary) |
EncryptedSerializer |
Decorator, transparent at-rest encryption |
'stores' => [ 'json-store' => [ 'driver' => 'redis', 'serializer' => 'json', // or 'php', 'igbinary' ], ],
Extending with Custom Drivers
$manager->extend('dynamodb', function (array $config) { return new DynamoDbStore($config); });
PHP 8.4 Features Used
- Property hooks —
CacheEntry,CacheStats,CacheEvent,TaggedCache,ChainStore - Asymmetric visibility —
CacheEntry,CacheLock,CacheEvent - Backed enums —
SerializerType,CacheEventType,LockState newin initializers — DefaultPhpSerializer()in constructorsmatchexpressions — Driver/serializer resolutiondeclare(strict_types=1)— Every file
Testing
php vendor/bin/phpunit --testdox
98 tests, 190 assertions — covers all stores, serializers, locks, tags, events, enums, and CacheManager.
License
MIT © MonkeysCloud