Cache
Igo.js uses Redis as a distributed cache.
Configuration
config.redis = {
socket: {
host: process.env.REDIS_HOST || '127.0.0.1',
port: process.env.REDIS_PORT || 6379,
},
database: process.env.REDIS_DATABASE || 0,
};Usage
const { cache } = require('@igojs/server');
// Store a value (with optional TTL in seconds)
await cache.put('users', 'user:123', { name: 'John' }, 3600);
// Retrieve a value
const user = await cache.get('users', 'user:123');
// => { name: 'John' } or null
// Retrieve several values of the same namespace, in one round trip
const users = await cache.mget('users', ['user:123', 'user:456']);
// => [{ name: 'John' }, 0] missing keys come back as 0
// Fetch: get from cache, or compute and store
const data = await cache.fetch('expensive', 'result', async () => {
return await expensiveComputation();
}, 1800);
// Delete
await cache.del('users', 'user:123');
// Increment a counter
await cache.incr('stats', 'page_views');
// Flush by pattern
await cache.flush('users/*');
// Flush everything
await cache.flushall();API
| Method | Description |
|---|---|
get(namespace, id) | Get a cached value (returns null if not found) |
mget(namespace, ids) | Get several values in order (missing keys return 0) |
put(namespace, id, value, timeout?) | Store a value with optional TTL (seconds) |
fetch(namespace, id, fn, timeout?) | Get or compute and cache |
del(namespace, id) | Delete a cached value |
incr(namespace, id) | Increment a counter |
flush(pattern) | Delete keys matching pattern (e.g. users/*) |
scan(pattern, fn) | Iterate over keys matching pattern |
flushdb() | Flush current database |
flushall() | Flush all databases |
info() | Redis server info |
isAvailable() | false while Redis is disabled, unreachable or reconnecting |
Availability
Redis is optional at runtime. While it is unavailable, no command throws: each one returns what it would have returned had it found or done nothing.
| Method | Degraded result |
|---|---|
get | null |
mget | 0 for every id — its usual value for a missing key |
put, flushdb, flushall, scan, flush | nothing happens |
del | 0 (no key removed) |
info | '' |
incr, incrby | null, not 0 |
incr is the exception: 0 is a real counter value, so a counter the caller cannot read is null — unknown. Code that gates on one (a rate limiter, a quota) has to decide what that means.
The client reconnects on its own and isAvailable() flips back without a restart — see Running without Redis.
Key Format
Keys are stored as namespace/id. For example, cache.get('users', 'user:123') reads the key users/user:123.
Serialization
Values are serialized with Node's structured clone (v8.serialize), so types survive the round trip: Date, Buffer, Map, Set and RegExp come back as themselves, falsy values are valid cache hits, functions are dropped and class instances come back as plain objects.
Two consequences:
- stored values are binary: unreadable with
redis-clior from another language; - an entry that cannot be read back — written by an Igo release still using JSON, or by a Node version using another format — is a cache miss and gets rewritten, rather than served with degraded types. Counters written by
incr/incrbyare plain integers, so a codec change never invalidates them.