Cache Service¶
The CacheService provides a unified, asynchronous interface for caching data. It abstracts the underlying storage (Memory or Redis), allowing plugins to use the same API regardless of the deployment environment.
Prerequisites¶
- Service Container overview understood
-
redisdriver installed (only if using the Redis backend)
Key Concepts¶
Backend Abstraction¶
Plugins interact with the CacheService facade, which delegates calls to either a MemoryBackend (standard Python dictionary with TTL) or a RedisCacheBackend.
Multi-Tenant Isolation¶
When tenancy.isolate_cache is enabled in xcore.yaml, the CacheService automatically prefixes every key with the current tenant_id. This prevents data leakage between tenants sharing the same Redis instance.
Practical Guide¶
1. Basic Operations¶
2. The get_or_set Pattern¶
Use this pattern to simplify your caching logic. It handles the "check-fetch-set" cycle in a single call.
factorycan be an async function, a sync function, or a static value.
3. Batch Operations¶
For high-performance scenarios, use mget and mset to reduce network round-trips.
API Reference¶
CacheService Methods¶
| Method | Return Type | Description |
|---|---|---|
get(key) |
Any \| None |
Retrieve a value by key. Returns None if expired or missing. |
set(key, value, ttl) |
None |
Store a value with an optional TTL (defaults to global config). |
delete(key) |
bool |
Remove a key. Returns True if it existed. |
exists(key) |
bool |
Check if a key exists without retrieving its value. |
get_or_set(key, factory, ttl) |
Any |
Returns cached value or calls factory() to populate it. |
mget(keys) |
dict |
Retrieve multiple keys in a single operation. |
mset(mapping, ttl) |
None |
Store multiple keys from a dictionary. |
clear() |
None |
Wipe all keys from the cache. |
YAML Configuration¶
| xcore.yaml | |
|---|---|
Common Errors & Pitfalls¶
Serialization Errors
The Redis backend uses pickle or json (depending on configuration) to serialize Python objects. Ensure your data is serializable.
Check: Complex objects with database connections or open files cannot be cached in Redis.
Memory Backend Volatility
Data in the memory backend is lost every time the server restarts. Use it only for transient data or small deployments.
Cache Stampede
If a very hot key expires, multiple requests might try to recompute it simultaneously. Use get_or_set to minimize this risk, though it does not yet include a global lock.
Best Practices¶
Granular TTLs
While a global TTL is convenient, always provide a specific ttl in your set() calls based on how often the data actually changes.
Use Namespacing
Always prefix your keys with a namespace (e.g., user:, order:) to avoid collisions between different plugins using the same cache service.