-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcache.zod.ts
More file actions
186 lines (167 loc) · 8.15 KB
/
cache.zod.ts
File metadata and controls
186 lines (167 loc) · 8.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { z } from 'zod';
/**
* Application-Level Cache Protocol
*
* Multi-tier caching strategy for application data.
* Supports Memory, Redis, Memcached, and CDN.
*
* ## Caching in ObjectStack
*
* **Application Cache (`system/cache.zod.ts`) - This File**
* - **Purpose**: Cache computed data, query results, aggregations
* - **Technologies**: Redis, Memcached, in-memory LRU
* - **Configuration**: TTL, eviction policies, cache warming
* - **Use case**: Cache expensive database queries, computed values
* - **Scope**: Application layer, server-side data storage
*
* **HTTP Cache (`api/http-cache.zod.ts`)**
* - **Purpose**: Cache API responses at HTTP protocol level
* - **Technologies**: HTTP headers (ETag, Last-Modified, Cache-Control), CDN
* - **Configuration**: Cache-Control headers, validation tokens
* - **Use case**: Reduce API response time for repeated metadata requests
* - **Scope**: HTTP layer, client-server communication
*
* @see ../../api/http-cache.zod.ts for HTTP-level caching
*/
export const CacheStrategySchema = z.enum([
'lru', // Least Recently Used
'lfu', // Least Frequently Used
'fifo', // First In First Out
'ttl', // Time To Live only
'adaptive', // Dynamic strategy selection
]).describe('Cache eviction strategy');
export type CacheStrategy = z.infer<typeof CacheStrategySchema>;
export const CacheTierSchema = z.object({
name: z.string().describe('Unique cache tier name'),
type: z.enum(['memory', 'redis', 'memcached', 'cdn']).describe('Cache backend type'),
maxSize: z.number().optional().describe('Max size in MB'),
ttl: z.number().default(300).describe('Default TTL in seconds'),
strategy: CacheStrategySchema.default('lru').describe('Eviction strategy'),
warmup: z.boolean().default(false).describe('Pre-populate cache on startup'),
}).describe('Configuration for a single cache tier in the hierarchy');
export type CacheTier = z.infer<typeof CacheTierSchema>;
export type CacheTierInput = z.input<typeof CacheTierSchema>;
export const CacheInvalidationSchema = z.object({
trigger: z.enum(['create', 'update', 'delete', 'manual']).describe('Event that triggers invalidation'),
scope: z.enum(['key', 'pattern', 'tag', 'all']).describe('Invalidation scope'),
pattern: z.string().optional().describe('Key pattern for pattern-based invalidation'),
tags: z.array(z.string()).optional().describe('Cache tags to invalidate'),
}).describe('Rule defining when and how cached entries are invalidated');
export type CacheInvalidation = z.infer<typeof CacheInvalidationSchema>;
export const CacheConfigSchema = z.object({
enabled: z.boolean().default(false).describe('Enable application-level caching'),
tiers: z.array(CacheTierSchema).describe('Ordered cache tier hierarchy'),
invalidation: z.array(CacheInvalidationSchema).describe('Cache invalidation rules'),
prefetch: z.boolean().default(false).describe('Enable cache prefetching'),
compression: z.boolean().default(false).describe('Enable data compression in cache'),
encryption: z.boolean().default(false).describe('Enable encryption for cached data'),
}).describe('Top-level application cache configuration');
export type CacheConfig = z.infer<typeof CacheConfigSchema>;
export type CacheConfigInput = z.input<typeof CacheConfigSchema>;
/**
* Distributed Cache Consistency Schema
*
* Defines write strategies for distributed cache consistency.
*
* - **write_through**: Write to cache and backend simultaneously
* - **write_behind**: Write to cache first, async persist to backend
* - **write_around**: Write to backend only, cache on next read
* - **refresh_ahead**: Proactively refresh expiring entries before TTL
*/
export const CacheConsistencySchema = z.enum([
'write_through',
'write_behind',
'write_around',
'refresh_ahead',
]).describe('Distributed cache write consistency strategy');
export type CacheConsistency = z.infer<typeof CacheConsistencySchema>;
/**
* Cache Avalanche Prevention Schema
*
* Strategies to prevent cache stampede/avalanche when many keys expire simultaneously.
*
* @example
* ```typescript
* const prevention: CacheAvalanchePrevention = {
* jitterTtl: { enabled: true, maxJitterSeconds: 60 },
* circuitBreaker: { enabled: true, failureThreshold: 5, resetTimeout: 30 },
* lockout: { enabled: true, lockTimeoutMs: 5000 },
* };
* ```
*/
export const CacheAvalanchePreventionSchema = z.object({
/** TTL jitter to stagger cache expiration */
jitterTtl: z.object({
enabled: z.boolean().default(false).describe('Add random jitter to TTL values'),
maxJitterSeconds: z.number().default(60).describe('Maximum jitter added to TTL in seconds'),
}).optional().describe('TTL jitter to prevent simultaneous expiration'),
/** Circuit breaker to protect backend under cache pressure */
circuitBreaker: z.object({
enabled: z.boolean().default(false).describe('Enable circuit breaker for backend protection'),
failureThreshold: z.number().default(5).describe('Failures before circuit opens'),
resetTimeout: z.number().default(30).describe('Seconds before half-open state'),
}).optional().describe('Circuit breaker for backend protection'),
/** Cache lock to prevent thundering herd on key miss */
lockout: z.object({
enabled: z.boolean().default(false).describe('Enable cache locking for key regeneration'),
lockTimeoutMs: z.number().default(5000).describe('Maximum lock wait time in milliseconds'),
}).optional().describe('Lock-based stampede prevention'),
}).describe('Cache avalanche/stampede prevention configuration');
export type CacheAvalanchePrevention = z.infer<typeof CacheAvalanchePreventionSchema>;
/**
* Cache Warmup Strategy Schema
*
* Defines how cache is pre-populated on startup or after cache flush.
*/
export const CacheWarmupSchema = z.object({
/** Enable cache warming */
enabled: z.boolean().default(false).describe('Enable cache warmup'),
/** Warmup strategy */
strategy: z.enum(['eager', 'lazy', 'scheduled']).default('lazy')
.describe('Warmup strategy: eager (at startup), lazy (on first access), scheduled (cron)'),
/** Cron schedule for scheduled warmup */
schedule: z.string().optional().describe('Cron expression for scheduled warmup'),
/** Keys/patterns to warm up */
patterns: z.array(z.string()).optional().describe('Key patterns to warm up (e.g., "user:*", "config:*")'),
/** Maximum concurrent warmup operations */
concurrency: z.number().default(10).describe('Maximum concurrent warmup operations'),
}).describe('Cache warmup strategy');
export type CacheWarmup = z.infer<typeof CacheWarmupSchema>;
/**
* Distributed Cache Configuration Schema
*
* Extended cache configuration for distributed multi-node deployments.
* Adds consistency strategies, avalanche prevention, and warmup policies.
*
* @example
* ```typescript
* const distributedCache: DistributedCacheConfig = {
* enabled: true,
* tiers: [
* { name: 'l1', type: 'memory', maxSize: 100, ttl: 60, strategy: 'lru' },
* { name: 'l2', type: 'redis', maxSize: 1000, ttl: 300, strategy: 'lru' },
* ],
* invalidation: [
* { trigger: 'update', scope: 'key' },
* ],
* consistency: 'write_through',
* avalanchePrevention: {
* jitterTtl: { enabled: true, maxJitterSeconds: 30 },
* circuitBreaker: { enabled: true, failureThreshold: 5 },
* },
* warmup: { enabled: true, strategy: 'eager', patterns: ['config:*'] },
* };
* ```
*/
export const DistributedCacheConfigSchema = CacheConfigSchema.extend({
/** Distributed write consistency strategy */
consistency: CacheConsistencySchema.optional().describe('Distributed cache consistency strategy'),
/** Avalanche/stampede prevention settings */
avalanchePrevention: CacheAvalanchePreventionSchema.optional()
.describe('Cache avalanche and stampede prevention'),
/** Cache warmup configuration */
warmup: CacheWarmupSchema.optional().describe('Cache warmup strategy'),
}).describe('Distributed cache configuration with consistency and avalanche prevention');
export type DistributedCacheConfig = z.infer<typeof DistributedCacheConfigSchema>;
export type DistributedCacheConfigInput = z.input<typeof DistributedCacheConfigSchema>;