Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
383 lines
8.3 KiB
Markdown
383 lines
8.3 KiB
Markdown
# Cache Manager Module
|
|
|
|
**Intelligent Caching for API Responses and Computed Values**
|
|
|
|
The Cache Manager Module provides a comprehensive caching system with multiple storage backends and caching strategies.
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- **Memory Cache** - Fast in-memory caching
|
|
- **IndexedDB Cache** - Persistent browser storage
|
|
- **Cache Strategies** - Multiple caching strategies (cache-first, network-first, stale-while-revalidate, etc.)
|
|
- **Cache Invalidation** - Pattern-based cache invalidation
|
|
- **Cache Warming** - Preload cache values
|
|
- **Cache Analytics** - Track cache performance
|
|
- **Integration with RequestDeduplicator** - Works with LiveComponent request deduplication
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### Basic Usage
|
|
|
|
```javascript
|
|
import { CacheManager, CacheStrategy } from './modules/cache-manager/index.js';
|
|
|
|
// Create cache manager
|
|
const cache = CacheManager.create({
|
|
defaultStrategy: CacheStrategy.STALE_WHILE_REVALIDATE,
|
|
defaultTTL: 3600000 // 1 hour
|
|
});
|
|
|
|
// Get or set value
|
|
const data = await cache.getOrSet('users', async () => {
|
|
const response = await fetch('/api/users');
|
|
return await response.json();
|
|
});
|
|
|
|
// Get from cache
|
|
const cached = await cache.get('users');
|
|
|
|
// Set in cache
|
|
await cache.set('users', data, { ttl: 1800000 }); // 30 minutes
|
|
```
|
|
|
|
### Module System Integration
|
|
|
|
```html
|
|
<!-- Enable global cache manager -->
|
|
<script type="module">
|
|
import { init } from './modules/cache-manager/index.js';
|
|
|
|
init({
|
|
defaultStrategy: 'stale-while-revalidate',
|
|
enableIndexedDB: true
|
|
});
|
|
</script>
|
|
|
|
<!-- Access globally -->
|
|
<script>
|
|
// Get or set
|
|
const data = await window.CacheManager.getOrSet('key', async () => {
|
|
return await fetch('/api/data').then(r => r.json());
|
|
});
|
|
</script>
|
|
```
|
|
|
|
---
|
|
|
|
## API Reference
|
|
|
|
### CacheManager.create(config)
|
|
|
|
Create a new CacheManager instance.
|
|
|
|
**Parameters**:
|
|
- `config.defaultStrategy` - Default caching strategy
|
|
- `config.defaultTTL` - Default time-to-live in milliseconds
|
|
- `config.maxMemorySize` - Maximum items in memory cache
|
|
- `config.enableIndexedDB` - Enable IndexedDB persistence
|
|
- `config.indexedDBName` - IndexedDB database name
|
|
- `config.enableAnalytics` - Enable cache analytics
|
|
|
|
**Example**:
|
|
```javascript
|
|
const cache = CacheManager.create({
|
|
defaultStrategy: CacheStrategy.STALE_WHILE_REVALIDATE,
|
|
defaultTTL: 3600000,
|
|
maxMemorySize: 100,
|
|
enableIndexedDB: true
|
|
});
|
|
```
|
|
|
|
### cache.get(key, options)
|
|
|
|
Get value from cache.
|
|
|
|
**Parameters**:
|
|
- `key` - Cache key
|
|
- `options.strategy` - Caching strategy override
|
|
- `options.ttl` - Time-to-live override
|
|
|
|
**Returns**: `Promise<any | null>`
|
|
|
|
### cache.set(key, value, options)
|
|
|
|
Set value in cache.
|
|
|
|
**Parameters**:
|
|
- `key` - Cache key
|
|
- `value` - Value to cache
|
|
- `options.strategy` - Caching strategy
|
|
- `options.ttl` - Time-to-live
|
|
|
|
**Returns**: `Promise<void>`
|
|
|
|
### cache.getOrSet(key, computeFn, options)
|
|
|
|
Get value from cache or compute and cache it.
|
|
|
|
**Parameters**:
|
|
- `key` - Cache key
|
|
- `computeFn` - Function to compute value if not cached
|
|
- `options` - Cache options
|
|
|
|
**Returns**: `Promise<any>`
|
|
|
|
**Example**:
|
|
```javascript
|
|
const users = await cache.getOrSet('users', async () => {
|
|
const response = await fetch('/api/users');
|
|
return await response.json();
|
|
}, { ttl: 1800000 });
|
|
```
|
|
|
|
### cache.delete(key)
|
|
|
|
Delete value from cache.
|
|
|
|
**Parameters**:
|
|
- `key` - Cache key
|
|
|
|
**Returns**: `Promise<void>`
|
|
|
|
### cache.clear()
|
|
|
|
Clear all cache.
|
|
|
|
**Returns**: `Promise<void>`
|
|
|
|
### cache.invalidate(pattern)
|
|
|
|
Invalidate cache entries matching a pattern.
|
|
|
|
**Parameters**:
|
|
- `pattern` - String, RegExp, or function
|
|
|
|
**Returns**: `Promise<void>`
|
|
|
|
**Example**:
|
|
```javascript
|
|
// Invalidate all user-related cache
|
|
await cache.invalidate('user:');
|
|
|
|
// Invalidate with regex
|
|
await cache.invalidate(/^user:\d+$/);
|
|
|
|
// Invalidate with function
|
|
await cache.invalidate(key => key.startsWith('user:'));
|
|
```
|
|
|
|
### cache.warm(keys, computeFn)
|
|
|
|
Warm cache by preloading values.
|
|
|
|
**Parameters**:
|
|
- `keys` - Array of cache keys
|
|
- `computeFn` - Function to compute value for each key
|
|
|
|
**Returns**: `Promise<void>`
|
|
|
|
**Example**:
|
|
```javascript
|
|
await cache.warm(['user:1', 'user:2', 'user:3'], async (key) => {
|
|
const userId = key.split(':')[1];
|
|
const response = await fetch(`/api/users/${userId}`);
|
|
return await response.json();
|
|
});
|
|
```
|
|
|
|
### cache.getAnalytics()
|
|
|
|
Get cache performance analytics.
|
|
|
|
**Returns**: `CacheAnalytics`
|
|
|
|
**Example**:
|
|
```javascript
|
|
const analytics = cache.getAnalytics();
|
|
console.log(`Hit rate: ${analytics.hitRate}%`);
|
|
console.log(`Hits: ${analytics.hits}, Misses: ${analytics.misses}`);
|
|
```
|
|
|
|
---
|
|
|
|
## Cache Strategies
|
|
|
|
### Cache-First
|
|
|
|
Use cache if available, otherwise fetch.
|
|
|
|
```javascript
|
|
const data = await cache.getOrSet('key', fetchData, {
|
|
strategy: CacheStrategy.CACHE_FIRST
|
|
});
|
|
```
|
|
|
|
### Network-First
|
|
|
|
Try network first, fallback to cache.
|
|
|
|
```javascript
|
|
const data = await cache.getOrSet('key', fetchData, {
|
|
strategy: CacheStrategy.NETWORK_FIRST
|
|
});
|
|
```
|
|
|
|
### Stale-While-Revalidate
|
|
|
|
Return cache immediately, update in background.
|
|
|
|
```javascript
|
|
const data = await cache.getOrSet('key', fetchData, {
|
|
strategy: CacheStrategy.STALE_WHILE_REVALIDATE
|
|
});
|
|
```
|
|
|
|
### Network-Only
|
|
|
|
Always fetch from network, never use cache.
|
|
|
|
```javascript
|
|
const data = await cache.getOrSet('key', fetchData, {
|
|
strategy: CacheStrategy.NETWORK_ONLY
|
|
});
|
|
```
|
|
|
|
### Cache-Only
|
|
|
|
Only use cache, never fetch from network.
|
|
|
|
```javascript
|
|
const data = await cache.get('key', {
|
|
strategy: CacheStrategy.CACHE_ONLY
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Integration with RequestDeduplicator
|
|
|
|
```javascript
|
|
import { CacheManager } from './modules/cache-manager/index.js';
|
|
import { RequestDeduplicator } from './modules/livecomponent/RequestDeduplicator.js';
|
|
|
|
const cache = CacheManager.create();
|
|
const deduplicator = new RequestDeduplicator();
|
|
|
|
// Use cache with request deduplication
|
|
async function fetchWithCache(url) {
|
|
return await cache.getOrSet(url, async () => {
|
|
// Check for pending request
|
|
const pending = deduplicator.getPendingRequest('api', 'GET', { url });
|
|
if (pending) {
|
|
return await pending;
|
|
}
|
|
|
|
// Make request
|
|
const promise = fetch(url).then(r => r.json());
|
|
deduplicator.registerPendingRequest('api', 'GET', { url }, promise);
|
|
|
|
return await promise;
|
|
});
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Use Cases
|
|
|
|
### API Response Caching
|
|
|
|
```javascript
|
|
const cache = CacheManager.create({
|
|
defaultStrategy: CacheStrategy.STALE_WHILE_REVALIDATE,
|
|
defaultTTL: 300000 // 5 minutes
|
|
});
|
|
|
|
async function getUsers() {
|
|
return await cache.getOrSet('api:users', async () => {
|
|
const response = await fetch('/api/users');
|
|
return await response.json();
|
|
});
|
|
}
|
|
```
|
|
|
|
### Computed Value Caching
|
|
|
|
```javascript
|
|
const cache = CacheManager.create();
|
|
|
|
function expensiveComputation(input) {
|
|
// Expensive operation
|
|
return input * 2;
|
|
}
|
|
|
|
async function getComputedValue(input) {
|
|
const key = `computed:${input}`;
|
|
return await cache.getOrSet(key, () => expensiveComputation(input), {
|
|
ttl: 3600000 // Cache for 1 hour
|
|
});
|
|
}
|
|
```
|
|
|
|
### Cache Invalidation
|
|
|
|
```javascript
|
|
// Invalidate all user-related cache when user updates
|
|
async function updateUser(userId, data) {
|
|
await fetch(`/api/users/${userId}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data)
|
|
});
|
|
|
|
// Invalidate related cache
|
|
await cache.invalidate(`user:${userId}`);
|
|
await cache.invalidate('users:list');
|
|
}
|
|
```
|
|
|
|
### Cache Warming
|
|
|
|
```javascript
|
|
// Warm cache on page load
|
|
async function warmCache() {
|
|
await cache.warm(['user:1', 'user:2', 'user:3'], async (key) => {
|
|
const userId = key.split(':')[1];
|
|
const response = await fetch(`/api/users/${userId}`);
|
|
return await response.json();
|
|
});
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
1. **Choose Appropriate Strategy** - Use cache-first for static data, network-first for dynamic data
|
|
2. **Set Appropriate TTL** - Balance freshness with performance
|
|
3. **Invalidate on Updates** - Clear cache when data changes
|
|
4. **Use Cache Warming** - Preload frequently accessed data
|
|
5. **Monitor Analytics** - Track cache performance and adjust strategy
|
|
|
|
---
|
|
|
|
## Browser Support
|
|
|
|
- **Chrome/Edge**: 90+
|
|
- **Firefox**: 88+
|
|
- **Safari**: 14+
|
|
- **Mobile**: iOS 14+, Android Chrome 90+
|
|
|
|
**Required Features**:
|
|
- ES2020 JavaScript
|
|
- IndexedDB (for persistent cache)
|
|
- Promise support
|
|
|
|
---
|
|
|
|
**Next**: Continue with Phase 3 modules →
|
|
|