fix: Gitea Traefik routing and connection pool optimization
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
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
This commit is contained in:
382
docs/modules/cache-manager.md
Normal file
382
docs/modules/cache-manager.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# 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 →
|
||||
|
||||
Reference in New Issue
Block a user