baja-lite 1.8.10 → 1.8.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cache.d.ts +15 -15
- package/cache.js +13 -13
- package/package.json +1 -1
package/cache.d.ts
CHANGED
|
@@ -72,10 +72,9 @@ export declare function MethodLock<T = any>(config: {
|
|
|
72
72
|
* - 关联清除(clearKey)生效。
|
|
73
73
|
* - 被清理的 key 如果启用了 StaleWhileRevalidate(CacheValue.sa=1),会保留旧值并标记 stale。
|
|
74
74
|
*
|
|
75
|
-
* @param key
|
|
76
|
-
* @param staleTimeoutSec stale 窗口秒数(仅对 StaleWhileRevalidate 的 key 生效)。默认 30。
|
|
75
|
+
* @param key 要清理的缓存 key 或 parent key
|
|
77
76
|
*/
|
|
78
|
-
export declare function clearMethodCache(key: string
|
|
77
|
+
export declare function clearMethodCache(key: string): Promise<void>;
|
|
79
78
|
/**
|
|
80
79
|
* 执行一个方法fn,
|
|
81
80
|
* 如果有缓存,则返回缓存,否则【加锁、二次检查】后执行方法并缓存,防止缓存击穿。
|
|
@@ -87,13 +86,17 @@ export declare function excuteWithCache<T>(config: {
|
|
|
87
86
|
key: ((...args: any[]) => string) | string;
|
|
88
87
|
/** 返回缓存清除key,参数=方法的参数+当前用户对象,可以用来批量清空缓存 */
|
|
89
88
|
clearKey?: string[];
|
|
90
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* 自动清空缓存的时间,单位分钟。
|
|
91
|
+
* ⚠️ 不能与 `staleMode: StaleWhileRevalidate` 同时使用:
|
|
92
|
+
* stale 只是把缓存"标记为过期",旧值仍在;而 autoClearTime 到期后会物理删除 key。
|
|
93
|
+
* 两者语义冲突——stale 期望保留旧值等后台刷新,autoClearTime 却会直接删掉它。
|
|
94
|
+
*/
|
|
91
95
|
autoClearTime?: number;
|
|
92
96
|
/** 是否缓存 null / undefined(负缓存防穿透),默认 false。 */
|
|
93
97
|
cacheNullValue?: boolean;
|
|
94
|
-
/** 负缓存 TTL
|
|
98
|
+
/** 负缓存 TTL(分钟)。默认沿用 autoClearTime;都不设时不写入。 */
|
|
95
99
|
nullCacheTime?: number;
|
|
96
|
-
/** 存储后端:'redis'(跨进程共享)。 */
|
|
97
100
|
/** 随着当前用户sesion的清空而一起清空 */
|
|
98
101
|
clearWithSession?: boolean;
|
|
99
102
|
/**
|
|
@@ -101,8 +104,6 @@ export declare function excuteWithCache<T>(config: {
|
|
|
101
104
|
* StaleWhileRevalidate 时设 sa=1 使 clearMethodCache 走"标记 stale + 保留旧值"路径。
|
|
102
105
|
*/
|
|
103
106
|
staleMode?: CacheStaleMode;
|
|
104
|
-
/** stale 窗口秒数(仅 StaleWhileRevalidate 生效)。默认 30。 */
|
|
105
|
-
staleTimeout?: number;
|
|
106
107
|
/**
|
|
107
108
|
* 缓存更新回调。异步方法,在 setMethodCache 成功写缓存后调用。
|
|
108
109
|
* 调用时三个参数:this → 方法的执行上下文(config.ctx);value → 缓存值;args → 方法输入参数。
|
|
@@ -116,7 +117,7 @@ export declare function excuteWithCache<T>(config: {
|
|
|
116
117
|
* key: 'calibration',
|
|
117
118
|
* ctx: service,
|
|
118
119
|
* args: ['device001'],
|
|
119
|
-
* onCacheUpdated(this: MyService,
|
|
120
|
+
* onCacheUpdated(this: MyService, value, args) {
|
|
120
121
|
* this.broadcast(value);
|
|
121
122
|
* },
|
|
122
123
|
* }, () => service.getCalibration('device001'));
|
|
@@ -133,7 +134,6 @@ export declare function excuteWithCache<T>(config: {
|
|
|
133
134
|
* 缓存注解:先查缓存 → miss 才加锁 → 锁内再查一次 → 仍 miss 才执行原方法。
|
|
134
135
|
* 已内置 single-flight,不需要再叠 `@MethodLock`。
|
|
135
136
|
* 可选 `cacheNullValue=true` 开启负缓存,防穿透。
|
|
136
|
-
* 可选 `storage: 'memory'` 用进程内 LRU 替代 redis(单进程场景,毫秒级延迟)。
|
|
137
137
|
* 可选 `staleMode: CacheStaleMode.StaleWhileRevalidate` 开启异步重新验证(清理时保留旧值,零阻塞)。
|
|
138
138
|
* 可选 `onCacheUpdated` 设置缓存更新回调(带 this 上下文)。
|
|
139
139
|
*/
|
|
@@ -142,13 +142,15 @@ export declare function MethodCache<T = any>(config: {
|
|
|
142
142
|
key: ((this: T, ...args: any[]) => string) | string;
|
|
143
143
|
/** 返回缓存清除key,参数=方法的参数[注意:必须和主方法的参数数量、完全一致,同时会追加一个当前用户对象]+当前用户对象,可以用来批量清空缓存 */
|
|
144
144
|
clearKey?: ((this: T, ...args: any[]) => string[]) | string[];
|
|
145
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* 自动清空缓存的时间,单位分钟。
|
|
147
|
+
* ⚠️ 不能与 `staleMode: StaleWhileRevalidate` 同用:stale 仅标记过期,autoClearTime 会物理删除 key,语义冲突。
|
|
148
|
+
*/
|
|
146
149
|
autoClearTime?: number;
|
|
147
150
|
/** 是否缓存 null / undefined(负缓存防穿透),默认 false。 */
|
|
148
151
|
cacheNullValue?: boolean;
|
|
149
152
|
/** 负缓存 TTL(分钟),默认沿用 autoClearTime。 */
|
|
150
153
|
nullCacheTime?: number;
|
|
151
|
-
/** 存储后端:'redis'(跨进程共享)。 */
|
|
152
154
|
/** 随着当前用户sesion的清空而一起清空 */
|
|
153
155
|
clearWithSession?: boolean;
|
|
154
156
|
/**
|
|
@@ -156,8 +158,6 @@ export declare function MethodCache<T = any>(config: {
|
|
|
156
158
|
* StaleWhileRevalidate 时设 sa=1 使 clearMethodCache 走"标记 stale + 保留旧值"路径。
|
|
157
159
|
*/
|
|
158
160
|
staleMode?: CacheStaleMode;
|
|
159
|
-
/** stale 窗口秒数(仅 StaleWhileRevalidate 生效)。默认 30。 */
|
|
160
|
-
staleTimeout?: number;
|
|
161
161
|
/**
|
|
162
162
|
* 缓存更新回调。异步方法,在 setMethodCache 成功写缓存后调用。
|
|
163
163
|
* 调用时三个参数:this → 执行上下文;args → 方法输入参数;value → 缓存值。
|
|
@@ -168,7 +168,7 @@ export declare function MethodCache<T = any>(config: {
|
|
|
168
168
|
* 外部直接设置缓存值。用于绕过 @MethodCache 装饰器直接更新缓存的场景
|
|
169
169
|
* (如外部事件驱动的数据变更、手动刷新等)。
|
|
170
170
|
*
|
|
171
|
-
* 内部使用统一格式 {
|
|
171
|
+
* 内部使用统一格式 { t, d, s, sa } 序列化,确保与 @MethodCache 的读取逻辑兼容。
|
|
172
172
|
*
|
|
173
173
|
* @param cacheKey 缓存 key(不含 [cache] 前缀,与 @MethodCache 的 key 一致)
|
|
174
174
|
* @param value 要缓存的值
|
package/cache.js
CHANGED
|
@@ -232,7 +232,7 @@ async function setMethodCache(config, devid) {
|
|
|
232
232
|
const event = CacheKey.value(config.key);
|
|
233
233
|
if (globalThis[_EventBus].listenerCount(event) === 0) {
|
|
234
234
|
globalThis[_EventBus].on(event, async (key) => {
|
|
235
|
-
await clearCacheKey(key
|
|
235
|
+
await clearCacheKey(key);
|
|
236
236
|
cacheLog(`cache ${key} clear by key!`);
|
|
237
237
|
});
|
|
238
238
|
}
|
|
@@ -241,8 +241,8 @@ async function setMethodCache(config, devid) {
|
|
|
241
241
|
// 订阅:清空 clear list —— 同样去重,避免每次 miss 都重复注册。
|
|
242
242
|
const event = `user-${devid}`;
|
|
243
243
|
if (globalThis[_EventBus].listenerCount(event) === 0) {
|
|
244
|
-
globalThis[_EventBus].on(event, async
|
|
245
|
-
await clearCacheKey(key
|
|
244
|
+
globalThis[_EventBus].on(event, async (key) => {
|
|
245
|
+
await clearCacheKey(key);
|
|
246
246
|
cacheLog(`cache ${key} clear by devid!`);
|
|
247
247
|
});
|
|
248
248
|
}
|
|
@@ -257,7 +257,7 @@ async function setMethodCache(config, devid) {
|
|
|
257
257
|
*
|
|
258
258
|
* @returns 受影响的 children 列表(parent 路径会返回所有被级联清理的 child key)
|
|
259
259
|
*/
|
|
260
|
-
async function clearCacheKey(key
|
|
260
|
+
async function clearCacheKey(key) {
|
|
261
261
|
const db = getRedisDB();
|
|
262
262
|
const affectedChildren = [];
|
|
263
263
|
// 1. 先处理 parent 级联:把关联的 children 全部清掉
|
|
@@ -266,7 +266,7 @@ async function clearCacheKey(key, staleTimeoutSec) {
|
|
|
266
266
|
const childKeys = await db.smembers(CacheKey.parent(key));
|
|
267
267
|
for (const child of childKeys) {
|
|
268
268
|
cacheLog(`cache ${child} cleared via parent ${key}!`);
|
|
269
|
-
await clearCacheKey(child
|
|
269
|
+
await clearCacheKey(child);
|
|
270
270
|
affectedChildren.push(child);
|
|
271
271
|
}
|
|
272
272
|
await db.del(CacheKey.parent(key));
|
|
@@ -313,14 +313,13 @@ async function clearCacheKey(key, staleTimeoutSec) {
|
|
|
313
313
|
* - 关联清除(clearKey)生效。
|
|
314
314
|
* - 被清理的 key 如果启用了 StaleWhileRevalidate(CacheValue.sa=1),会保留旧值并标记 stale。
|
|
315
315
|
*
|
|
316
|
-
* @param key
|
|
317
|
-
* @param staleTimeoutSec stale 窗口秒数(仅对 StaleWhileRevalidate 的 key 生效)。默认 30。
|
|
316
|
+
* @param key 要清理的缓存 key 或 parent key
|
|
318
317
|
*/
|
|
319
|
-
export async function clearMethodCache(key
|
|
318
|
+
export async function clearMethodCache(key) {
|
|
320
319
|
const redisDao = globalThis[_dao]?.[DBType.Redis]?.[_primaryDB];
|
|
321
320
|
if (!redisDao)
|
|
322
321
|
return;
|
|
323
|
-
await clearCacheKey(key
|
|
322
|
+
await clearCacheKey(key);
|
|
324
323
|
}
|
|
325
324
|
/**
|
|
326
325
|
* Redis 缓存执行:先查缓存 → miss 后单飞抢锁执行 → 其它等待者只盯缓存、不抢锁。
|
|
@@ -333,7 +332,7 @@ export async function clearMethodCache(key, staleTimeoutSec = 30) {
|
|
|
333
332
|
* 命中判断用 `cached !== null`(ioredis 在 key 不存在时返回 `null`),
|
|
334
333
|
* 这样 `cacheNullValue=true` 时存进去的字面量 `'null'` 也会算作命中,达到防穿透效果。
|
|
335
334
|
*
|
|
336
|
-
* 命中时若发现 stale
|
|
335
|
+
* 命中时若发现 stale 标志(CacheValue.s=1),说明该值是"已被声明过期但保留的旧值",
|
|
337
336
|
* 此时仍返回旧值(零阻塞),同时触发后台 single-flight 异步刷新。
|
|
338
337
|
* 这样 clearMethodCache 后的首次读取不会被阻塞,后续读取将命中刷新后的新值。
|
|
339
338
|
*
|
|
@@ -518,7 +517,6 @@ export async function excuteWithCache(config, fn) {
|
|
|
518
517
|
* 缓存注解:先查缓存 → miss 才加锁 → 锁内再查一次 → 仍 miss 才执行原方法。
|
|
519
518
|
* 已内置 single-flight,不需要再叠 `@MethodLock`。
|
|
520
519
|
* 可选 `cacheNullValue=true` 开启负缓存,防穿透。
|
|
521
|
-
* 可选 `storage: 'memory'` 用进程内 LRU 替代 redis(单进程场景,毫秒级延迟)。
|
|
522
520
|
* 可选 `staleMode: CacheStaleMode.StaleWhileRevalidate` 开启异步重新验证(清理时保留旧值,零阻塞)。
|
|
523
521
|
* 可选 `onCacheUpdated` 设置缓存更新回调(带 this 上下文)。
|
|
524
522
|
*/
|
|
@@ -551,7 +549,7 @@ export function MethodCache(config) {
|
|
|
551
549
|
* 外部直接设置缓存值。用于绕过 @MethodCache 装饰器直接更新缓存的场景
|
|
552
550
|
* (如外部事件驱动的数据变更、手动刷新等)。
|
|
553
551
|
*
|
|
554
|
-
* 内部使用统一格式 {
|
|
552
|
+
* 内部使用统一格式 { t, d, s, sa } 序列化,确保与 @MethodCache 的读取逻辑兼容。
|
|
555
553
|
*
|
|
556
554
|
* @param cacheKey 缓存 key(不含 [cache] 前缀,与 @MethodCache 的 key 一致)
|
|
557
555
|
* @param value 要缓存的值
|
|
@@ -579,8 +577,10 @@ export async function setCache(cacheKey, value, options = {}) {
|
|
|
579
577
|
}
|
|
580
578
|
const dataStr = isNullish ? 'null' : JSON.stringify(value);
|
|
581
579
|
const timestamp = Date.now();
|
|
582
|
-
const payload = serializeCacheValue(dataStr, timestamp);
|
|
583
580
|
const db = getRedisDB();
|
|
581
|
+
// 保留旧 sa:沿用已有标志(防止外部直写清掉 sa=1,导致 clearMethodCache 变 purge)
|
|
582
|
+
const existingSa = await db.get(CacheKey.value(cacheKey)).then(r => r ? deserializeCacheValue(r).sa : undefined);
|
|
583
|
+
const payload = serializeCacheValue(dataStr, timestamp, false, !!existingSa);
|
|
584
584
|
if (autoClearTime) {
|
|
585
585
|
await db.set(CacheKey.value(cacheKey), payload, 'EX', autoClearTime * 60);
|
|
586
586
|
}
|