@abtnode/db-cache 1.17.8-beta-20260119-034126-467341b7 → 1.17.8-beta-20260121-102603-f9d0176f
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/dist/index.cjs +10 -6
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +8 -6
- package/dist/index.mjs.map +1 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,9 @@ const fs = require('node:fs');
|
|
|
6
6
|
const path = require('node:path');
|
|
7
7
|
const node_util = require('node:util');
|
|
8
8
|
const sqlite3 = require('sqlite3');
|
|
9
|
+
const eventHubCluster = require('@arcblock/event-hub');
|
|
10
|
+
const eventHubSingle = require('@arcblock/event-hub/single');
|
|
11
|
+
const lruCache = require('lru-cache');
|
|
9
12
|
|
|
10
13
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
14
|
|
|
@@ -25,6 +28,8 @@ const path__default = /*#__PURE__*/_interopDefaultCompat(path$1);
|
|
|
25
28
|
const fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs);
|
|
26
29
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
27
30
|
const sqlite3__default = /*#__PURE__*/_interopDefaultCompat(sqlite3);
|
|
31
|
+
const eventHubCluster__namespace = /*#__PURE__*/_interopNamespaceCompat(eventHubCluster);
|
|
32
|
+
const eventHubSingle__namespace = /*#__PURE__*/_interopNamespaceCompat(eventHubSingle);
|
|
28
33
|
|
|
29
34
|
function ulid() {
|
|
30
35
|
const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
@@ -242,10 +247,8 @@ var __publicField$4 = (obj, key, value) => {
|
|
|
242
247
|
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
243
248
|
return value;
|
|
244
249
|
};
|
|
245
|
-
const lruCacheModule = require("lru-cache");
|
|
246
|
-
const LRUCacheLib = lruCacheModule?.LRUCache || lruCacheModule?.default || lruCacheModule;
|
|
247
250
|
const isTestEnv = process.env.NODE_ENV === "test";
|
|
248
|
-
const eventHub = isTestEnv ?
|
|
251
|
+
const eventHub = isTestEnv ? eventHubSingle__namespace : eventHubCluster__namespace;
|
|
249
252
|
const LRU_CACHE_SYNC_EVENT = "db-cache:lru:sync";
|
|
250
253
|
const LRU_CACHE_DELETE_EVENT = "db-cache:lru:delete";
|
|
251
254
|
const LRU_CACHE_CLEAR_EVENT = "db-cache:lru:clear";
|
|
@@ -266,7 +269,7 @@ const _LruCache = class _LruCache {
|
|
|
266
269
|
if (!_LruCache.caches.has(this.cacheKey)) {
|
|
267
270
|
_LruCache.caches.set(
|
|
268
271
|
this.cacheKey,
|
|
269
|
-
new
|
|
272
|
+
new lruCache.LRUCache({
|
|
270
273
|
max: this.maxSize,
|
|
271
274
|
ttl: 0
|
|
272
275
|
// 我们自己管理 TTL
|
|
@@ -298,7 +301,7 @@ const _LruCache = class _LruCache {
|
|
|
298
301
|
if (!groupCaches.has(key)) {
|
|
299
302
|
groupCaches.set(
|
|
300
303
|
key,
|
|
301
|
-
new
|
|
304
|
+
new lruCache.LRUCache({
|
|
302
305
|
max: this.maxSize,
|
|
303
306
|
ttl: 0
|
|
304
307
|
})
|
|
@@ -319,7 +322,7 @@ const _LruCache = class _LruCache {
|
|
|
319
322
|
if (isGroup && subKey !== void 0) {
|
|
320
323
|
const groupCaches = _LruCache.groupCaches.get(cacheKey);
|
|
321
324
|
if (groupCaches) {
|
|
322
|
-
const groupCache = groupCaches.get(key) || new
|
|
325
|
+
const groupCache = groupCaches.get(key) || new lruCache.LRUCache({ max: maxSize, ttl: 0 });
|
|
323
326
|
groupCache.set(subKey, entry);
|
|
324
327
|
groupCaches.set(key, groupCache);
|
|
325
328
|
}
|
|
@@ -1328,3 +1331,4 @@ exports.DBCache = LockDBCache;
|
|
|
1328
1331
|
exports.LruCache = LruCache;
|
|
1329
1332
|
exports.getAbtNodeRedisAndSQLiteUrl = getAbtNodeRedisAndSQLiteUrl;
|
|
1330
1333
|
exports.withRetry = withRetry;
|
|
1334
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../tools/ulid.ts","../src/adapter/redis-adapter.ts","../src/with-retry.ts","../src/lru-cache.ts","../src/adapter/sqlite-adapter.ts","../src/base-db-cache.ts","../src/single-flight-db-cache.ts","../src/lock-db-cache.ts","../src/index.ts"],"sourcesContent":["export function ulid() {\n const alphabet = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\n\n // 时间部分(10 chars)\n let t = Date.now();\n let timeStr = '';\n for (let i = 0; i < 10; i++) {\n timeStr = alphabet[t % 32] + timeStr;\n t = Math.floor(t / 32);\n }\n\n // 随机部分直接用 Math.random().toString(32)\n // 去掉 \"0.\",取 16 个字符,不足时递补\n let rand = Math.random().toString(32).substring(2);\n while (rand.length < 16) {\n rand += Math.random().toString(32).substring(2);\n }\n rand = rand.substring(0, 16).toUpperCase();\n\n return timeStr + rand;\n}\n","/* eslint-disable prettier/prettier */\n// eslint-disable-next-line max-classes-per-file\nimport { createClient, type RedisClientType } from 'redis';\nimport type { BaseDBCacheParams, IDBAdapter } from './adapter';\n\nexport class RedisAdapter implements IDBAdapter {\n clearAll(): Promise<void> {\n throw new Error('Method not implemented.');\n }\n\n public opts: BaseDBCacheParams = null as unknown as BaseDBCacheParams;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static clients: Map<string, RedisClientType<any, any>> = new Map();\n\n private static initPromises: Map<string, Promise<void>> = new Map();\n\n public defaultTtl: number = 1000 * 60 * 60;\n\n private url = '';\n\n public prefix: string = '';\n\n private prefixKey = (key: string) => `${this.prefix}:${key}`;\n\n private prefixKeyGroup = (key: string) => `${this.prefix}:group:${key}`;\n\n public async ensure(): Promise<void> {\n if (!this.url) {\n this.url = this.opts.redisUrl || '';\n this.prefix = this.opts.prefix;\n this.defaultTtl = this.opts.ttl;\n }\n\n if (RedisAdapter.clients.has(this.url)) {\n return;\n }\n\n if (!RedisAdapter.initPromises.has(this.url)) {\n RedisAdapter.initPromises.set(\n this.url,\n (async () => {\n const { url } = this;\n if (!url) {\n throw new Error('Redis URL is not set');\n }\n const cli = createClient({ url });\n cli.on('error', console.error);\n await cli.connect();\n await cli.ping();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RedisAdapter.clients.set(url, cli as RedisClientType<any, any>);\n })()\n );\n }\n\n await RedisAdapter.initPromises.get(this.url);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private getClient(): RedisClientType<any, any> {\n if (!this.url || !RedisAdapter.clients.has(this.url)) {\n throw new Error('Redis not initialized');\n }\n const client = RedisAdapter.clients.get(this.url);\n if (!client) {\n throw new Error('Redis client not found');\n }\n return client;\n }\n\n public serialize(value: unknown): string {\n return JSON.stringify({ v: value });\n }\n\n public deserialize(raw: string | null | undefined): unknown {\n if (raw === null || raw === undefined) return null;\n try {\n const obj = JSON.parse(raw);\n return (obj as { v: unknown }).v;\n } catch {\n return null;\n }\n }\n\n public async set(key: string, value: unknown, { ttl, nx }: { ttl?: number; nx?: boolean }): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const effectiveTtl = ttl !== undefined ? ttl : this.defaultTtl;\n\n /* ----------- NX via both file-lock and Redis NX ------------ */\n let result: string | null;\n if (effectiveTtl && effectiveTtl > 0) {\n result = await client.set(storageKey, this.serialize(value), { PX: effectiveTtl, NX: nx });\n } else {\n result = await client.set(storageKey, this.serialize(value), { NX: nx });\n }\n\n if (result !== 'OK') {\n const storedValue = await client.get(storageKey);\n if (storedValue === this.serialize(value)) {\n // ghost success\n return true;\n }\n return false;\n }\n\n return result === 'OK';\n }\n\n public async get(key: string): Promise<unknown> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const raw = await client.get(storageKey);\n return this.deserialize(raw);\n }\n\n public async del(key: string): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const storageKeyGroup = this.prefixKeyGroup(key);\n await client.del(storageKey);\n await client.del(storageKeyGroup);\n }\n\n public async has(key: string): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const exists = await client.exists(storageKey);\n if (exists === 0) return false;\n const raw = await client.get(storageKey);\n if (!raw) return false;\n const data = JSON.parse(raw) as { v: unknown; e: number | null };\n if (data.e && Date.now() > data.e) {\n await this.del(key);\n return false;\n }\n return true;\n }\n\n public async groupSet(key: string, subKey: string, value: unknown, { ttl }: { ttl?: number }): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n await client.hSet(storageKey, subKey, this.serialize(value));\n const effectiveTtl = ttl !== undefined ? ttl : this.defaultTtl;\n if (effectiveTtl > 0) {\n await client.expire(storageKey, Math.ceil(effectiveTtl / 1000));\n }\n }\n\n public async groupGet(key: string, subKey: string): Promise<unknown> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n const raw = await client.hGet(storageKey, subKey);\n return this.deserialize(raw);\n }\n\n public async groupHas(key: string, subKey: string): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n return (await client.hExists(storageKey, subKey)) === 1;\n }\n\n public async groupDel(key: string, subKey: string): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n await client.hDel(storageKey, subKey);\n }\n\n public async close(): Promise<void> {\n if (this.url && RedisAdapter.clients.has(this.url)) {\n const client = RedisAdapter.clients.get(this.url);\n if (client) {\n await client.quit();\n RedisAdapter.clients.delete(this.url);\n RedisAdapter.initPromises.delete(this.url);\n }\n }\n }\n\n public async flushAll(): Promise<void> {\n const client = this.getClient();\n await client.flushAll();\n }\n\n /**\n * 获取 LRU 缓存统计信息(Redis 不使用 LRU 缓存)\n */\n public getLruCacheStats(): { size: number; groupCount: number; maxSize: number } | null {\n return null;\n }\n}\n","/* eslint-disable no-await-in-loop */\n/* eslint-disable no-constant-condition */\n// eslint-disable-next-line no-promise-executor-return\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\ninterface WithRetryOptions {\n /** 最大重试次数 */\n max?: number;\n /** 初始退避时长,单位 ms */\n backoffBase?: number;\n /** 每次重试时的指数倍数 */\n backoffExponent?: number;\n /** 抖动范围,0~backoffJitter 毫秒 */\n backoffJitter?: number;\n /** 判断是否需要重试的函数 */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n needRetry?: (err: any) => boolean;\n}\n\n// 通用指数退避重试\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n {\n max = 15,\n backoffBase = 200,\n backoffExponent = 1.1,\n backoffJitter = 100,\n needRetry = () => true,\n // eslint-disable-next-line @typescript-eslint/comma-dangle\n }: WithRetryOptions = {}\n): Promise<T> {\n let attempt = 0;\n\n while (true) {\n try {\n return await fn();\n } catch (err) {\n // 超过最大重试次数或不需要重试,抛出错误\n if (!needRetry(err) || ++attempt > max) {\n throw err;\n }\n\n // 计算指数退避延迟:base * exponent^(attempt-1)\n const exp = backoffExponent ** (attempt - 1);\n const expDelay = backoffBase * exp;\n // 加上随机抖动\n const jitter = Math.random() * backoffJitter;\n const waitTime = Math.floor(expDelay + jitter);\n\n // 等待后重试\n await sleep(waitTime);\n }\n }\n}\n","/* eslint-disable prettier/prettier */\n/* eslint-disable max-classes-per-file */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// @ts-expect-error - event-hub 没有类型定义\nimport * as eventHubCluster from '@arcblock/event-hub';\n// @ts-expect-error - event-hub 没有类型定义\nimport * as eventHubSingle from '@arcblock/event-hub/single';\nimport { LRUCache } from 'lru-cache';\n\nconst isTestEnv = process.env.NODE_ENV === 'test';\n\n// 根据环境选择 event-hub 版本:测试环境使用单进程版本,生产环境使用集群版本\nconst eventHub = isTestEnv ? eventHubSingle : eventHubCluster;\n\nconst LRU_CACHE_SYNC_EVENT = 'db-cache:lru:sync';\nconst LRU_CACHE_DELETE_EVENT = 'db-cache:lru:delete';\nconst LRU_CACHE_CLEAR_EVENT = 'db-cache:lru:clear';\n\ninterface CacheEntry {\n value: string;\n expiresAt: number | null;\n}\n\n// LRU 缓存实例类型\ntype LRUCacheInstance = LRUCache<string, CacheEntry>;\n\ninterface SyncEventPayload {\n channel: string;\n key: string;\n value: string;\n expiresAt: number | null;\n isGroup?: boolean;\n subKey?: string;\n}\n\ninterface DeleteEventPayload {\n channel: string;\n keys: string[];\n isGroup?: boolean;\n groupKey?: string;\n}\n\ninterface ClearEventPayload {\n channel: string;\n}\n\n/**\n * 判断是否需要跨 worker 同步\n * - 测试环境不需要同步\n * - 非 cluster 模式(NODE_APP_INSTANCE 未定义)不需要同步\n */\nconst shouldEnableSync = (): boolean => {\n if (isTestEnv) {\n return false;\n }\n // NODE_APP_INSTANCE 由 PM2 在 cluster 模式下设置\n return process.env.NODE_APP_INSTANCE !== undefined;\n};\n\nexport interface LruCacheOptions {\n /** 缓存前缀,用于区分不同的缓存实例 */\n prefix: string;\n /** 最大缓存条数,默认 10000 */\n maxSize?: number;\n /** 是否启用跨 worker 同步,默认 true(在支持的环境中) */\n enableSync?: boolean;\n}\n\n/**\n * LRU 内存缓存工具类\n *\n * 特点:\n * 1. 基于 LRU 算法的内存缓存\n * 2. 支持 TTL 过期\n * 3. 支持 Node.js 集群模式下的跨 worker 同步\n * 4. 可单独使用,也可作为 Redis/SQLite 适配器的 L1 缓存层\n *\n * CLUSTER MODE NOTE:\n * 当运行在 cluster 模式下时,缓存数据会通过 event hub 广播给所有 worker,\n * 确保所有 worker 的内存缓存数据一致。\n */\nexport class LruCache {\n private static caches: Map<string, LRUCacheInstance> = new Map();\n\n private static groupCaches: Map<string, Map<string, LRUCacheInstance>> = new Map();\n\n private static listenerSetup: Map<string, boolean> = new Map();\n\n private cacheKey: string;\n\n private maxSize: number;\n\n private enableSync: boolean;\n\n constructor(options: LruCacheOptions) {\n this.cacheKey = `lru:${options.prefix}`;\n this.maxSize = options.maxSize ?? 10000;\n this.enableSync = (options.enableSync ?? true) && shouldEnableSync();\n\n if (!LruCache.caches.has(this.cacheKey)) {\n LruCache.caches.set(\n this.cacheKey,\n new LRUCache({\n max: this.maxSize,\n ttl: 0, // 我们自己管理 TTL\n })\n );\n LruCache.groupCaches.set(this.cacheKey, new Map());\n\n // 设置同步监听器\n if (this.enableSync && !LruCache.listenerSetup.has(this.cacheKey)) {\n this._setupSyncListener();\n LruCache.listenerSetup.set(this.cacheKey, true);\n }\n }\n }\n\n private getCache(): LRUCacheInstance {\n const cache = LruCache.caches.get(this.cacheKey);\n if (!cache) {\n throw new Error('LRU cache not initialized');\n }\n return cache;\n }\n\n private getGroupCaches(): Map<string, LRUCacheInstance> {\n const groupCaches = LruCache.groupCaches.get(this.cacheKey);\n if (!groupCaches) {\n throw new Error('LRU group cache not initialized');\n }\n return groupCaches;\n }\n\n private getOrCreateGroupCache(key: string): LRUCacheInstance {\n const groupCaches = this.getGroupCaches();\n if (!groupCaches.has(key)) {\n groupCaches.set(\n key,\n new LRUCache({\n max: this.maxSize,\n ttl: 0,\n })\n );\n }\n return groupCaches.get(key)!;\n }\n\n /**\n * 设置同步监听器,接收其他 worker 广播的缓存数据\n */\n private _setupSyncListener(): void {\n const { cacheKey, maxSize } = this;\n\n eventHub.on(LRU_CACHE_SYNC_EVENT, (payload: SyncEventPayload) => {\n const { channel, key, value, expiresAt, isGroup, subKey } = payload;\n if (channel !== cacheKey) return;\n\n const entry: CacheEntry = { value, expiresAt };\n\n if (isGroup && subKey !== undefined) {\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n const groupCache = groupCaches.get(key) || new LRUCache({ max: maxSize, ttl: 0 });\n groupCache.set(subKey, entry);\n groupCaches.set(key, groupCache);\n }\n } else {\n const cache = LruCache.caches.get(cacheKey);\n if (cache) {\n cache.set(key, entry);\n }\n }\n });\n\n eventHub.on(LRU_CACHE_DELETE_EVENT, (payload: DeleteEventPayload) => {\n const { channel, keys, isGroup, groupKey } = payload;\n if (channel !== cacheKey) return;\n\n if (isGroup && groupKey !== undefined) {\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n const groupCache = groupCaches.get(groupKey);\n if (groupCache) {\n for (const key of keys) {\n groupCache.delete(key);\n }\n }\n }\n } else {\n const cache = LruCache.caches.get(cacheKey);\n if (cache) {\n for (const key of keys) {\n cache.delete(key);\n // 同时删除相关的 group cache\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n groupCaches.delete(key);\n }\n }\n }\n }\n });\n\n eventHub.on(LRU_CACHE_CLEAR_EVENT, (payload: ClearEventPayload) => {\n const { channel } = payload;\n if (channel !== cacheKey) return;\n\n const cache = LruCache.caches.get(cacheKey);\n if (cache) {\n cache.clear();\n }\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n groupCaches.clear();\n }\n });\n }\n\n /**\n * 广播缓存数据给其他 worker\n */\n private _broadcastSync(key: string, value: string, expiresAt: number | null, isGroup = false, subKey?: string): void {\n if (this.enableSync) {\n eventHub.broadcast(LRU_CACHE_SYNC_EVENT, {\n channel: this.cacheKey,\n key,\n value,\n expiresAt,\n isGroup,\n subKey,\n });\n }\n }\n\n /**\n * 广播删除缓存给其他 worker\n */\n private _broadcastDelete(keys: string[], isGroup = false, groupKey?: string): void {\n if (this.enableSync && keys.length > 0) {\n eventHub.broadcast(LRU_CACHE_DELETE_EVENT, {\n channel: this.cacheKey,\n keys,\n isGroup,\n groupKey,\n });\n }\n }\n\n /**\n * 广播清空缓存给其他 worker\n */\n private _broadcastClear(): void {\n if (this.enableSync) {\n eventHub.broadcast(LRU_CACHE_CLEAR_EVENT, {\n channel: this.cacheKey,\n });\n }\n }\n\n private isExpired(entry: CacheEntry | undefined): boolean {\n if (!entry) return true;\n if (entry.expiresAt !== null && Date.now() > entry.expiresAt) {\n return true;\n }\n return false;\n }\n\n /* ---------------------- 基础 API ---------------------- */\n\n /**\n * 设置缓存\n * @param key 缓存键\n * @param value 序列化后的值\n * @param expiresAt 过期时间戳,null 表示永不过期\n */\n set(key: string, value: string, expiresAt: number | null): void {\n const cache = this.getCache();\n const entry: CacheEntry = { value, expiresAt };\n cache.set(key, entry);\n this._broadcastSync(key, value, expiresAt);\n }\n\n /**\n * 获取缓存\n * @param key 缓存键\n * @returns 序列化的值,未命中或过期返回 null\n */\n get(key: string): string | null {\n const cache = this.getCache();\n const entry = cache.get(key) as CacheEntry | undefined;\n\n if (!entry) return null;\n if (this.isExpired(entry)) {\n cache.delete(key);\n return null;\n }\n\n return entry.value;\n }\n\n /**\n * 检查缓存是否存在且未过期\n */\n has(key: string): boolean {\n const cache = this.getCache();\n const entry = cache.get(key) as CacheEntry | undefined;\n\n if (!entry) return false;\n if (this.isExpired(entry)) {\n cache.delete(key);\n return false;\n }\n\n return true;\n }\n\n /**\n * 删除缓存\n */\n del(key: string): void {\n const cache = this.getCache();\n cache.delete(key);\n\n // 同时删除相关的 group cache\n const groupCaches = this.getGroupCaches();\n groupCaches.delete(key);\n\n this._broadcastDelete([key]);\n }\n\n /**\n * 按前缀删除缓存\n * @returns 删除的数量\n */\n delByPrefix(prefix: string): number {\n const cache = this.getCache();\n const deletedKeys: string[] = [];\n\n for (const key of cache.keys()) {\n if ((key as string).startsWith(prefix)) {\n cache.delete(key);\n deletedKeys.push(key as string);\n }\n }\n\n // 同时删除匹配前缀的 group caches\n const groupCaches = this.getGroupCaches();\n for (const key of groupCaches.keys()) {\n if (key.startsWith(prefix)) {\n groupCaches.delete(key);\n }\n }\n\n this._broadcastDelete(deletedKeys);\n return deletedKeys.length;\n }\n\n /* ---------------------- 分组 API ---------------------- */\n\n /**\n * 设置分组缓存\n */\n groupSet(key: string, subKey: string, value: string, expiresAt: number | null): void {\n const groupCache = this.getOrCreateGroupCache(key);\n const entry: CacheEntry = { value, expiresAt };\n groupCache.set(subKey, entry);\n this._broadcastSync(key, value, expiresAt, true, subKey);\n }\n\n /**\n * 获取分组缓存\n */\n groupGet(key: string, subKey: string): string | null {\n const groupCaches = this.getGroupCaches();\n const groupCache = groupCaches.get(key);\n\n if (!groupCache) return null;\n\n const entry = groupCache.get(subKey) as CacheEntry | undefined;\n if (!entry) return null;\n if (this.isExpired(entry)) {\n groupCache.delete(subKey);\n return null;\n }\n\n return entry.value;\n }\n\n /**\n * 检查分组缓存是否存在\n */\n groupHas(key: string, subKey: string): boolean {\n const groupCaches = this.getGroupCaches();\n const groupCache = groupCaches.get(key);\n\n if (!groupCache) return false;\n\n const entry = groupCache.get(subKey) as CacheEntry | undefined;\n if (!entry) return false;\n if (this.isExpired(entry)) {\n groupCache.delete(subKey);\n return false;\n }\n\n return true;\n }\n\n /**\n * 删除分组缓存\n */\n groupDel(key: string, subKey: string): void {\n const groupCaches = this.getGroupCaches();\n const groupCache = groupCaches.get(key);\n\n if (groupCache) {\n groupCache.delete(subKey);\n this._broadcastDelete([subKey], true, key);\n }\n }\n\n /* ---------------------- 管理 API ---------------------- */\n\n /**\n * 清空所有缓存\n */\n clear(): void {\n const cache = this.getCache();\n cache.clear();\n\n const groupCaches = this.getGroupCaches();\n groupCaches.clear();\n\n this._broadcastClear();\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): { size: number; groupCount: number; maxSize: number } {\n const cache = this.getCache();\n const groupCaches = this.getGroupCaches();\n\n let totalGroupSize = 0;\n for (const groupCache of groupCaches.values()) {\n totalGroupSize += groupCache.size;\n }\n\n return {\n size: cache.size, // 普通缓存条目数\n groupCount: totalGroupSize, // 分组缓存条目数\n maxSize: this.maxSize, // 最大容量\n };\n }\n\n /**\n * 关闭缓存(清理资源)\n *\n * 注意:不会广播 close 事件给其他 worker,因为每个 worker 有独立的生命周期\n */\n close(): void {\n // 移除 event listeners(避免内存泄漏)\n // 注意:eventHub 可能没有提供 off 方法,这取决于具体实现\n // 如果没有 off 方法,listeners 会在进程结束时自动清理\n\n LruCache.caches.delete(this.cacheKey);\n LruCache.groupCaches.delete(this.cacheKey);\n LruCache.listenerSetup.delete(this.cacheKey);\n }\n}\n","/* eslint-disable require-await */\n/* eslint-disable prettier/prettier */\n/* eslint-disable no-promise-executor-return */\n/* eslint-disable max-classes-per-file */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable @typescript-eslint/comma-dangle */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\nimport sqlite3, { type Database } from 'sqlite3';\nimport { withRetry } from '../with-retry';\nimport type { BaseDBCacheParams, IDBAdapter } from './adapter';\nimport { LruCache } from '../lru-cache';\n\nconst retryOptions = {\n needRetry: (err: Error) => err.message?.includes('SQLITE_BUSY') || err.message?.includes('disk I/O'),\n};\n\nconst dbRun = (db: sqlite3.Database, sql: string, params?: unknown[]) => {\n return withRetry(() => {\n return new Promise<void>((res, rej) => {\n db.run(sql, params, (err: Error | null) => (err ? rej(err) : res()));\n });\n }, retryOptions);\n};\n\nconst dbExec = (db: sqlite3.Database, sql: string) => {\n return withRetry(() => {\n return new Promise<void>((res, rej) => {\n db.exec(sql, (err: Error | null) => (err ? rej(err) : res()));\n });\n }, retryOptions);\n};\n\nconst dbGet = <T>(db: sqlite3.Database, sql: string, params?: unknown[]) => {\n return withRetry(() => {\n return new Promise<T>((res, rej) => {\n db.get(sql, params, (err: Error | null, result: unknown) => (err ? rej(err) : res(result as T)));\n });\n }, retryOptions);\n};\n\nasync function initSqliteWithRetry(db: sqlite3.Database) {\n db.configure('busyTimeout', 5000);\n\n try {\n await dbExec(\n db,\n `\n PRAGMA journal_mode = WAL;\n PRAGMA synchronous = normal;\n PRAGMA wal_autocheckpoint = 5000;\n PRAGMA busy_timeout = 5000;\n `\n );\n\n await dbRun(\n db,\n `\n CREATE TABLE IF NOT EXISTS kvcache (\n key TEXT NOT NULL,\n subKey TEXT NOT NULL,\n value TEXT NOT NULL,\n expiresAt INTEGER,\n PRIMARY KEY (key, subKey)\n )\n `\n );\n } catch (err) {\n throw new Error(`SQLite init failed: ${err}`);\n }\n}\n\nexport class SqliteAdapter implements IDBAdapter {\n public opts: BaseDBCacheParams = null as unknown as BaseDBCacheParams;\n\n private static clients: Map<string, Database> = new Map();\n\n private static initPromises: Map<string, Promise<void>> = new Map();\n\n private static cleanupTimers: Map<string, NodeJS.Timeout> = new Map();\n\n private static lruCaches: Map<string, LruCache> = new Map();\n\n /** LRU 缓存的最大条数上限 */\n private static readonly MAX_LRU_CACHE_SIZE = 100;\n\n public prefix: string = '';\n\n public defaultTtl: number = 1000 * 60 * 60;\n\n private cleanupInterval: number = 5 * 60 * 1000;\n\n private dbPath: string = '';\n\n private enableLruCache: boolean = false;\n\n private lruCache: LruCache | null = null;\n\n /* ------------------------------- init ------------------------------- */\n\n public async ensure(): Promise<void> {\n const isMemory = this.opts.sqlitePath === ':memory:';\n if (!this.dbPath) {\n this.dbPath = isMemory ? ':memory:' : path.resolve(this.opts.sqlitePath);\n this.prefix = this.opts.prefix;\n this.defaultTtl = this.opts.ttl;\n this.cleanupInterval = this.opts.cleanupInterval ?? 5 * 60 * 1000;\n this.enableLruCache = this.opts.enableLruCache ?? false;\n }\n\n // 初始化 LRU 缓存层\n if (this.enableLruCache && !this.lruCache) {\n const lruCacheKey = `sqlite:${this.dbPath}:${this.prefix}`;\n if (!SqliteAdapter.lruCaches.has(lruCacheKey)) {\n const requestedSize = this.opts.lruMaxSize ?? 100;\n const actualSize = Math.min(requestedSize, SqliteAdapter.MAX_LRU_CACHE_SIZE);\n\n if (requestedSize > SqliteAdapter.MAX_LRU_CACHE_SIZE) {\n console.warn(\n `[SqliteAdapter] Requested LRU cache size ${requestedSize} exceeds maximum ${SqliteAdapter.MAX_LRU_CACHE_SIZE}, using ${actualSize} instead`\n );\n }\n\n SqliteAdapter.lruCaches.set(\n lruCacheKey,\n new LruCache({\n prefix: lruCacheKey,\n maxSize: actualSize,\n enableSync: this.opts.enableSync ?? true,\n })\n );\n }\n this.lruCache = SqliteAdapter.lruCaches.get(lruCacheKey)!;\n }\n\n if (SqliteAdapter.clients.has(this.dbPath)) return;\n\n if (!SqliteAdapter.initPromises.has(this.dbPath)) {\n if (!isMemory) {\n const dir = path.dirname(this.dbPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n }\n\n SqliteAdapter.initPromises.set(\n this.dbPath,\n (async () => {\n const db = new sqlite3.Database(this.dbPath);\n await initSqliteWithRetry(db);\n\n SqliteAdapter.clients.set(this.dbPath, db);\n SqliteAdapter.cleanupTimers.set(\n this.dbPath,\n setInterval(\n () => {\n this.cleanup().catch(console.error);\n },\n this.cleanupInterval + Math.random() * 30000\n )\n );\n })()\n );\n }\n\n await SqliteAdapter.initPromises.get(this.dbPath);\n }\n\n private getClient(): Database {\n if (!this.dbPath || !SqliteAdapter.clients.has(this.dbPath)) {\n throw new Error('SQLite not initialized');\n }\n return SqliteAdapter.clients.get(this.dbPath)!;\n }\n\n /* ------------------------------- cleanup ------------------------------- */\n\n private async cleanup(): Promise<void> {\n const client = this.getClient();\n await dbRun(client, 'DELETE FROM kvcache WHERE expiresAt IS NOT NULL AND expiresAt <= ?', [Date.now()]);\n }\n\n /* ------------------------------- core ------------------------------- */\n\n private prefixKey(key: string): string {\n return `${this.prefix}:${key}`;\n }\n\n public serialize(value: unknown): string {\n return JSON.stringify({ v: value });\n }\n\n public deserialize(raw: string | null | undefined): unknown {\n if (raw === null || raw === undefined) return null;\n try {\n return (JSON.parse(raw) as { v: unknown }).v;\n } catch {\n return null;\n }\n }\n\n public async set(key: string, value: unknown, opts: { ttl?: number; nx?: boolean }): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : null;\n const serializedValue = this.serialize(value);\n\n // 对于 NX 选项,先检查 key 是否存在\n if (opts.nx) {\n // 先检查 L1 缓存\n if (this.lruCache?.has(storageKey)) {\n return false;\n }\n // 再检查 L2 数据库\n const existing = await dbGet<{ value: string }>(\n client,\n 'SELECT value FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, '']\n );\n if (existing) {\n return false;\n }\n }\n\n // 写入 L2 数据库\n await dbRun(\n client,\n `\n INSERT INTO kvcache (key, subKey, value, expiresAt)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(key, subKey) DO UPDATE SET\n value = excluded.value,\n expiresAt = excluded.expiresAt\n `,\n [storageKey, '', serializedValue, expiresAt]\n );\n\n // 写入 L1 缓存\n if (this.lruCache) {\n this.lruCache.set(storageKey, serializedValue, expiresAt);\n }\n\n return true;\n }\n\n public async get(key: string): Promise<unknown> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache) {\n const cached = this.lruCache.get(storageKey);\n if (cached !== null) {\n return this.deserialize(cached);\n }\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ value: string; expiresAt: number | null }>(\n client,\n 'SELECT value, \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, '']\n );\n\n if (!row) return null;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.del(key);\n return null;\n }\n\n // 写入 L1 缓存(回填)\n if (this.lruCache) {\n this.lruCache.set(storageKey, row.value, row.expiresAt);\n }\n\n return this.deserialize(row.value);\n }\n\n public async del(key: string): Promise<void> {\n const storageKey = this.prefixKey(key);\n\n // 删除 L1 缓存\n if (this.lruCache) {\n this.lruCache.del(storageKey);\n }\n\n // 删除 L2 数据库\n const client = this.getClient();\n await dbRun(client, 'DELETE FROM kvcache WHERE key = ?', [storageKey]);\n }\n\n public async has(key: string): Promise<boolean> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache?.has(storageKey)) {\n return true;\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ expiresAt: number | null }>(\n client,\n 'SELECT \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, '']\n );\n\n if (!row) return false;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.del(key);\n return false;\n }\n\n return true;\n }\n\n /* ------------------------------- group APIs ------------------------------- */\n\n public async groupSet(\n key: string,\n subKey: string,\n value: unknown,\n opts: { ttl?: number; nx?: boolean }\n ): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : null;\n const serializedValue = this.serialize(value);\n\n // 写入 L2 数据库(UPSERT)\n await dbRun(\n client,\n `\n INSERT INTO kvcache (key, subKey, value, expiresAt)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(key, subKey) DO UPDATE SET\n value = excluded.value,\n expiresAt = excluded.expiresAt\n `,\n [storageKey, subKey, serializedValue, expiresAt]\n );\n\n // 写入 L1 缓存\n if (this.lruCache) {\n this.lruCache.groupSet(storageKey, subKey, serializedValue, expiresAt);\n }\n }\n\n public async groupGet(key: string, subKey: string): Promise<unknown> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache) {\n const cached = this.lruCache.groupGet(storageKey, subKey);\n if (cached !== null) {\n return this.deserialize(cached);\n }\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ value: string; expiresAt: number | null }>(\n client,\n 'SELECT value, \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, subKey]\n );\n\n if (!row) return null;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.groupDel(key, subKey);\n return null;\n }\n\n // 写入 L1 缓存(回填)\n if (this.lruCache) {\n this.lruCache.groupSet(storageKey, subKey, row.value, row.expiresAt);\n }\n\n return this.deserialize(row.value);\n }\n\n public async groupHas(key: string, subKey: string): Promise<boolean> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache?.groupHas(storageKey, subKey)) {\n return true;\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ expiresAt: number | null }>(\n client,\n 'SELECT \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, subKey]\n );\n\n if (!row) return false;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.groupDel(key, subKey);\n return false;\n }\n\n return true;\n }\n\n public async groupDel(key: string, subKey: string): Promise<void> {\n const storageKey = this.prefixKey(key);\n\n // 删除 L1 缓存\n if (this.lruCache) {\n this.lruCache.groupDel(storageKey, subKey);\n }\n\n // 删除 L2 数据库\n const client = this.getClient();\n await dbRun(client, 'DELETE FROM kvcache WHERE key = ? AND subKey = ?', [storageKey, subKey]);\n }\n\n /* ------------------------------- misc ------------------------------- */\n\n public async close(): Promise<void> {\n // 关闭 LRU 缓存\n if (this.lruCache) {\n this.lruCache.close();\n const lruCacheKey = `sqlite:${this.dbPath}:${this.prefix}`;\n SqliteAdapter.lruCaches.delete(lruCacheKey);\n this.lruCache = null;\n }\n\n if (this.dbPath) {\n const timer = SqliteAdapter.cleanupTimers.get(this.dbPath);\n if (timer) {\n clearInterval(timer);\n SqliteAdapter.cleanupTimers.delete(this.dbPath);\n }\n\n const client = SqliteAdapter.clients.get(this.dbPath);\n if (client) {\n client.close();\n SqliteAdapter.clients.delete(this.dbPath);\n SqliteAdapter.initPromises.delete(this.dbPath);\n }\n }\n }\n\n public async flushAll(): Promise<void> {\n // 清空 L1 缓存\n if (this.lruCache) {\n this.lruCache.clear();\n }\n\n // 清空 L2 数据库\n const client = this.getClient();\n const run = promisify(client.run.bind(client));\n await run('DELETE FROM kvcache');\n }\n\n /**\n * 获取 LRU 缓存统计信息\n */\n public getLruCacheStats(): { size: number; groupCount: number; maxSize: number } | null {\n if (!this.lruCache) {\n return null;\n }\n return this.lruCache.getStats();\n }\n}\n","/* eslint-disable prettier/prettier */\n// base-db-cache.ts\nimport { RedisAdapter } from './adapter/redis-adapter';\nimport { SqliteAdapter } from './adapter/sqlite-adapter';\nimport { BaseDBCacheOptions, IDBAdapter } from './adapter/adapter';\n\nexport class BaseDBCache {\n private adapter: IDBAdapter = null as unknown as IDBAdapter;\n\n public prefix: string = '';\n\n public type: string = '';\n\n public defaultTtl: number = 0;\n\n private getOpts: BaseDBCacheOptions;\n\n private _initdAdapter: boolean = false;\n\n constructor(opts: BaseDBCacheOptions) {\n this.getOpts = opts;\n }\n\n protected initAdapter(): void {\n if (this._initdAdapter) {\n return;\n }\n\n\n if (typeof this.getOpts !== 'function') {\n throw new Error('getOpts must be a function');\n }\n\n const opts = this.getOpts();\n\n if (!opts.prefix || typeof opts.prefix !== 'string' || opts.prefix.trim() === '') {\n throw new Error('prefix is required');\n }\n if (!opts.sqlitePath || typeof opts.sqlitePath !== 'string') {\n throw new Error('sqlitePath is required');\n }\n if (typeof opts.ttl !== 'number' || opts.ttl < 0) {\n throw new Error('ttl must be a non-negative number');\n }\n\n if (opts.cleanupInterval && opts.cleanupInterval < 1000 * 60 * 5) {\n console.error('cleanupInterval must be at least 5 minutes');\n throw new Error('cleanupInterval must be at least 5 minutes');\n }\n\n this.type = opts.forceType || (opts.redisUrl ? 'redis' : 'sqlite');\n\n this.prefix = opts.prefix;\n this.defaultTtl = opts.ttl;\n\n switch (this.type) {\n case 'redis':\n this.adapter = new RedisAdapter();\n this.adapter.opts = opts;\n break;\n case 'sqlite':\n this.adapter = new SqliteAdapter();\n this.adapter.opts = opts;\n break;\n default:\n throw new Error(`Unsupported backend: ${this.type}`);\n }\n\n this._initdAdapter = true;\n\n }\n\n static randomKey(): string {\n return Math.random().toString(36).substring(2, 15);\n }\n\n public async set(key: string, value: unknown, opts: { ttl?: number; nx?: boolean } = {}): Promise<boolean> {\n this.initAdapter();\n\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve(false);\n }\n // Determine TTL: provided or default\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n if (typeof effectiveTtl !== 'number' || effectiveTtl < 0) {\n console.error('ttl must be a non-negative number');\n throw new Error('ttl must be a non-negative number');\n }\n await this.adapter.ensure();\n return this.adapter.set(key, value, { ttl: effectiveTtl, nx: opts.nx });\n }\n\n public async get(key: string): Promise<unknown> {\n this.initAdapter();\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve();\n }\n\n await this.adapter.ensure();\n return this.adapter.get(key);\n }\n\n public async del(key: string): Promise<void> {\n this.initAdapter();\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve();\n }\n await this.adapter.ensure();\n return this.adapter.del(key);\n }\n\n public async has(key: string): Promise<boolean> {\n this.initAdapter();\n\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve(false);\n }\n await this.adapter.ensure();\n return this.adapter.has(key);\n }\n\n public async groupSet(\n key: string,\n subKey: string,\n value: unknown,\n opts: { ttl?: number; nx?: boolean } = {},\n ): Promise<void> {\n this.initAdapter();\n\n if (typeof key !== 'string' || typeof subKey !== 'string') {\n return Promise.resolve();\n }\n // Determine TTL: provided or default\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n if (typeof effectiveTtl !== 'number' || effectiveTtl < 0) {\n console.error('ttl must be a non-negative number');\n throw new Error('ttl must be a non-negative number');\n }\n await this.adapter.ensure();\n return this.adapter.groupSet(key, subKey, value, { ttl: effectiveTtl, nx: opts.nx });\n }\n\n public async groupGet(key: string, subKey: string): Promise<unknown> {\n this.initAdapter();\n\n if (typeof key !== 'string' || typeof subKey !== 'string') {\n console.error('key must be a string');\n return null;\n }\n await this.adapter.ensure();\n return this.adapter.groupGet(key, subKey);\n }\n\n public async groupHas(key: string, subKey: string): Promise<boolean> {\n this.initAdapter();\n\n if (typeof key !== 'string') {\n throw new Error('key must be a string');\n }\n if (typeof subKey !== 'string') {\n throw new Error('subKey must be a string');\n }\n\n await this.adapter.ensure();\n return this.adapter.groupHas(key, subKey);\n }\n\n public async groupDel(key: string, subKey: string): Promise<void> {\n this.initAdapter();\n\n if (!key || !subKey) {\n return Promise.resolve();\n }\n await this.adapter.ensure();\n\n return this.adapter.groupDel(key, subKey);\n }\n\n public async close(): Promise<void> {\n this.initAdapter();\n\n await this.adapter.ensure();\n\n return this.adapter.close();\n }\n\n public async flushAll(): Promise<void> {\n this.initAdapter();\n await this.adapter.ensure();\n return this.adapter.flushAll();\n }\n\n /**\n * 获取 LRU 缓存统计信息\n * @returns 缓存统计信息,如果未启用 LRU 缓存则返回 null\n */\n public getLruCacheStats(): { size: number; groupCount: number; maxSize: number } | null {\n this.initAdapter();\n return this.adapter.getLruCacheStats();\n }\n}\n","/* eslint-disable prettier/prettier */\nimport { BaseDBCache } from './base-db-cache';\nimport { BaseDBCacheOptions } from './adapter/adapter';\n\nexport default class SingleFlightDBCache extends BaseDBCache {\n private _pending: Map<string, Promise<unknown>>;\n\n constructor(opts: BaseDBCacheOptions) {\n super(opts);\n this._pending = new Map<string, Promise<unknown>>();\n }\n\n /**\n * If a request for the same key is already in flight, reuse it.\n * Otherwise, fetch, cache, and return the value.\n */\n public autoCache<T>(key: string, fn: () => Promise<T>, { ttl }: { ttl?: number } = {}): Promise<T> {\n this.initAdapter();\n // Treat empty key as bypassing cache\n if (!key) {\n return fn();\n }\n\n if (typeof key !== 'string') {\n throw new Error('key must be a string');\n }\n\n if (this._pending.has(key)) {\n return this._pending.get(key) as Promise<T>;\n }\n\n const task = (async (): Promise<T> => {\n try {\n const hit = (await super.get(key)) as T | null;\n if (hit !== null) {\n return hit;\n }\n const result = await fn();\n await super.set(key, result, { ttl });\n return result;\n } finally {\n this._pending.delete(key);\n }\n })();\n\n this._pending.set(key, task);\n return task;\n }\n\n /**\n * Same logic as autoCache, but for group fields (hash).\n */\n public autoCacheGroup<T>(\n key: string,\n subKey: string,\n fn: () => Promise<T>,\n { ttl }: { ttl?: number } = {},\n ): Promise<T> {\n this.initAdapter();\n // Treat missing key or subKey as bypass\n if (!key || !subKey) {\n return fn();\n }\n\n if (typeof key !== 'string') {\n throw new Error('key must be a string');\n }\n\n if (typeof subKey !== 'string') {\n throw new Error('subKey must be a string');\n }\n\n const pendingKey = `${key}-${subKey}`;\n if (this._pending.has(pendingKey)) {\n return this._pending.get(pendingKey) as Promise<T>;\n }\n\n const task = (async (): Promise<T> => {\n try {\n const hit = (await super.groupGet(key, subKey)) as T | null;\n if (hit !== null) {\n return hit;\n }\n const result = await fn();\n await super.groupSet(key, subKey, result, { ttl });\n return result;\n } finally {\n this._pending.delete(pendingKey);\n }\n })();\n\n this._pending.set(pendingKey, task);\n return task;\n }\n}\n","/* eslint-disable no-await-in-loop */\nimport { ulid } from '../tools/ulid';\nimport SingleFlightDBCache from './single-flight-db-cache';\n\nexport default class LockDBCache extends SingleFlightDBCache {\n private _inFlight: Map<string, number> = new Map();\n\n public async createLock(lockName: string): Promise<boolean> {\n this.initAdapter();\n if (!lockName) {\n return false;\n }\n const key = this._formatLockKey(lockName);\n\n // 如果本地标记已经在进行\"抢锁\"操作,直接返回 false\n // 注意:这只是本地优化,真正的锁在 Redis/SQLite 中\n const lastLockTime = this._inFlight.get(key);\n if (lastLockTime && Date.now() - lastLockTime < this.defaultTtl) {\n return false;\n }\n\n // 标记正在抢锁\n this._inFlight.set(key, Date.now());\n\n try {\n // 直接使用 SET NX 原子操作来获取锁,不需要先检查再设置\n // SET key value NX PX ttl 是原子操作:\n // - 如果 key 不存在,设置成功并返回 \"OK\"\n // - 如果 key 已存在,不设置并返回 null\n // 这样可以避免 Check-Then-Act 竞态条件\n const result = await this.set(key, ulid(), { ttl: this.defaultTtl, nx: true });\n return result;\n } finally {\n // 无论成功或失败,一定要把 inFlight 标记删除\n this._inFlight.delete(key);\n // 清空过期时间\n for (const [key2, value] of this._inFlight.entries()) {\n if (Date.now() - value > this.defaultTtl) {\n this._inFlight.delete(key2);\n }\n }\n }\n }\n\n /**\n * 检查锁是否已经过期:只要缓存层面已经没有该 key,就代表已过期或从未创建。\n *\n * @param lockName 锁的名称\n * @returns 如果锁不存在或已过期,返回 true;否则返回 false\n */\n public async hasExpired(lockName: string): Promise<boolean> {\n this.initAdapter();\n if (!lockName) {\n return true;\n }\n const key = this._formatLockKey(lockName);\n const exists = await this.has(key);\n return !exists;\n }\n\n /**\n * 主动释放锁:删除对应的缓存 key\n *\n * @param lockName 锁的名称\n */\n public async releaseLock(lockName: string): Promise<void> {\n this.initAdapter();\n if (!lockName) {\n return;\n }\n const key = this._formatLockKey(lockName);\n await this.del(key);\n }\n\n /**\n * 等待锁释放或超时。每隔 100ms 检查一次缓存层面是否仍存在该锁 key。\n * 如果在 timeoutMs 毫秒内 key 不再存在,则 resolve(true)。否则 resolve(false)。\n *\n * @param lockName 锁的名称\n * @param timeoutMs 等待超时时间(毫秒),默认使用构造时传入的 this._timeout\n * @returns 如果锁被释放或过期,resolve(true);等待到超时还没释放,则 resolve(false)\n */\n // eslint-disable-next-line require-await\n public async waitUnLock(lockName: string, timeoutMs: number = this.defaultTtl): Promise<boolean> {\n this.initAdapter();\n\n if (!lockName) {\n return true;\n }\n const key = this._formatLockKey(lockName);\n const start = Date.now();\n\n return new Promise((resolve) => {\n const interval = setInterval(async () => {\n const exists = await this.has(key);\n if (!exists) {\n clearInterval(interval);\n resolve(true);\n } else if (Date.now() - start >= timeoutMs) {\n clearInterval(interval);\n resolve(false);\n }\n // 否则继续等待\n }, 100);\n });\n }\n\n /**\n * 获取锁的流程:\n * 1. 先尝试 createLock(lockName):\n * - 如果立刻拿到(createLock 返回 true),直接返回;\n * - 如果没拿到,就等待 waitUnLock(lockName)。\n * 2. 等待到释放/过期后,再次尝试 createLock(lockName)。\n *\n * @param lockName 锁的名称\n */\n public async acquire(lockName: string): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const acquired = await this.createLock(lockName);\n if (acquired) {\n return;\n }\n await this.waitUnLock(lockName);\n }\n }\n\n private _formatLockKey(lockName: string): string {\n return `lock:${this.prefix}:${lockName}`;\n }\n}\n","import path from 'path';\nimport { BaseDBCacheParams } from './adapter/adapter';\nimport DBCache from './lock-db-cache';\nimport { withRetry } from './with-retry';\nimport { LruCache } from './lru-cache';\n\nexport type { BaseDBCacheOptions, IDBAdapter, ForceType } from './adapter/adapter';\nexport { LruCache };\n\nconst isJestTest = () => {\n return process.env.NODE_ENV === 'test' || process.env.BABEL_ENV === 'test';\n};\n\nexport const getAbtNodeRedisAndSQLiteUrl = () => {\n const blockletCacheDir = process.env.BLOCKLET_DATA_DIR\n ? path.join(process.env.BLOCKLET_DATA_DIR, '__default-cache-store.db')\n : undefined;\n const params = {\n redisUrl: process.env.ABT_NODE_CACHE_REDIS_URL,\n sqlitePath: isJestTest() ? ':memory:' : blockletCacheDir || process.env.ABT_NODE_CACHE_SQLITE_PATH,\n };\n if (process.env.ABT_NODE_NO_CACHE === 'true') {\n (params as unknown as BaseDBCacheParams).ttl = 1;\n }\n return params;\n};\n\nexport { DBCache, withRetry };\n"],"names":["__publicField","createClient","eventHubSingle","eventHubCluster","LRUCache","path","fs","sqlite3","promisify"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,9 @@ import * as fs from 'node:fs';
|
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
6
|
import sqlite3 from 'sqlite3';
|
|
7
|
+
import * as eventHubCluster from '@arcblock/event-hub';
|
|
8
|
+
import * as eventHubSingle from '@arcblock/event-hub/single';
|
|
9
|
+
import { LRUCache } from 'lru-cache';
|
|
7
10
|
|
|
8
11
|
function ulid() {
|
|
9
12
|
const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
@@ -221,10 +224,8 @@ var __publicField$4 = (obj, key, value) => {
|
|
|
221
224
|
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
222
225
|
return value;
|
|
223
226
|
};
|
|
224
|
-
const lruCacheModule = require("lru-cache");
|
|
225
|
-
const LRUCacheLib = lruCacheModule?.LRUCache || lruCacheModule?.default || lruCacheModule;
|
|
226
227
|
const isTestEnv = process.env.NODE_ENV === "test";
|
|
227
|
-
const eventHub = isTestEnv ?
|
|
228
|
+
const eventHub = isTestEnv ? eventHubSingle : eventHubCluster;
|
|
228
229
|
const LRU_CACHE_SYNC_EVENT = "db-cache:lru:sync";
|
|
229
230
|
const LRU_CACHE_DELETE_EVENT = "db-cache:lru:delete";
|
|
230
231
|
const LRU_CACHE_CLEAR_EVENT = "db-cache:lru:clear";
|
|
@@ -245,7 +246,7 @@ const _LruCache = class _LruCache {
|
|
|
245
246
|
if (!_LruCache.caches.has(this.cacheKey)) {
|
|
246
247
|
_LruCache.caches.set(
|
|
247
248
|
this.cacheKey,
|
|
248
|
-
new
|
|
249
|
+
new LRUCache({
|
|
249
250
|
max: this.maxSize,
|
|
250
251
|
ttl: 0
|
|
251
252
|
// 我们自己管理 TTL
|
|
@@ -277,7 +278,7 @@ const _LruCache = class _LruCache {
|
|
|
277
278
|
if (!groupCaches.has(key)) {
|
|
278
279
|
groupCaches.set(
|
|
279
280
|
key,
|
|
280
|
-
new
|
|
281
|
+
new LRUCache({
|
|
281
282
|
max: this.maxSize,
|
|
282
283
|
ttl: 0
|
|
283
284
|
})
|
|
@@ -298,7 +299,7 @@ const _LruCache = class _LruCache {
|
|
|
298
299
|
if (isGroup && subKey !== void 0) {
|
|
299
300
|
const groupCaches = _LruCache.groupCaches.get(cacheKey);
|
|
300
301
|
if (groupCaches) {
|
|
301
|
-
const groupCache = groupCaches.get(key) || new
|
|
302
|
+
const groupCache = groupCaches.get(key) || new LRUCache({ max: maxSize, ttl: 0 });
|
|
302
303
|
groupCache.set(subKey, entry);
|
|
303
304
|
groupCaches.set(key, groupCache);
|
|
304
305
|
}
|
|
@@ -1304,3 +1305,4 @@ const getAbtNodeRedisAndSQLiteUrl = () => {
|
|
|
1304
1305
|
};
|
|
1305
1306
|
|
|
1306
1307
|
export { LockDBCache as DBCache, LruCache, getAbtNodeRedisAndSQLiteUrl, withRetry };
|
|
1308
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../tools/ulid.ts","../src/adapter/redis-adapter.ts","../src/with-retry.ts","../src/lru-cache.ts","../src/adapter/sqlite-adapter.ts","../src/base-db-cache.ts","../src/single-flight-db-cache.ts","../src/lock-db-cache.ts","../src/index.ts"],"sourcesContent":["export function ulid() {\n const alphabet = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\n\n // 时间部分(10 chars)\n let t = Date.now();\n let timeStr = '';\n for (let i = 0; i < 10; i++) {\n timeStr = alphabet[t % 32] + timeStr;\n t = Math.floor(t / 32);\n }\n\n // 随机部分直接用 Math.random().toString(32)\n // 去掉 \"0.\",取 16 个字符,不足时递补\n let rand = Math.random().toString(32).substring(2);\n while (rand.length < 16) {\n rand += Math.random().toString(32).substring(2);\n }\n rand = rand.substring(0, 16).toUpperCase();\n\n return timeStr + rand;\n}\n","/* eslint-disable prettier/prettier */\n// eslint-disable-next-line max-classes-per-file\nimport { createClient, type RedisClientType } from 'redis';\nimport type { BaseDBCacheParams, IDBAdapter } from './adapter';\n\nexport class RedisAdapter implements IDBAdapter {\n clearAll(): Promise<void> {\n throw new Error('Method not implemented.');\n }\n\n public opts: BaseDBCacheParams = null as unknown as BaseDBCacheParams;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static clients: Map<string, RedisClientType<any, any>> = new Map();\n\n private static initPromises: Map<string, Promise<void>> = new Map();\n\n public defaultTtl: number = 1000 * 60 * 60;\n\n private url = '';\n\n public prefix: string = '';\n\n private prefixKey = (key: string) => `${this.prefix}:${key}`;\n\n private prefixKeyGroup = (key: string) => `${this.prefix}:group:${key}`;\n\n public async ensure(): Promise<void> {\n if (!this.url) {\n this.url = this.opts.redisUrl || '';\n this.prefix = this.opts.prefix;\n this.defaultTtl = this.opts.ttl;\n }\n\n if (RedisAdapter.clients.has(this.url)) {\n return;\n }\n\n if (!RedisAdapter.initPromises.has(this.url)) {\n RedisAdapter.initPromises.set(\n this.url,\n (async () => {\n const { url } = this;\n if (!url) {\n throw new Error('Redis URL is not set');\n }\n const cli = createClient({ url });\n cli.on('error', console.error);\n await cli.connect();\n await cli.ping();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RedisAdapter.clients.set(url, cli as RedisClientType<any, any>);\n })()\n );\n }\n\n await RedisAdapter.initPromises.get(this.url);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private getClient(): RedisClientType<any, any> {\n if (!this.url || !RedisAdapter.clients.has(this.url)) {\n throw new Error('Redis not initialized');\n }\n const client = RedisAdapter.clients.get(this.url);\n if (!client) {\n throw new Error('Redis client not found');\n }\n return client;\n }\n\n public serialize(value: unknown): string {\n return JSON.stringify({ v: value });\n }\n\n public deserialize(raw: string | null | undefined): unknown {\n if (raw === null || raw === undefined) return null;\n try {\n const obj = JSON.parse(raw);\n return (obj as { v: unknown }).v;\n } catch {\n return null;\n }\n }\n\n public async set(key: string, value: unknown, { ttl, nx }: { ttl?: number; nx?: boolean }): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const effectiveTtl = ttl !== undefined ? ttl : this.defaultTtl;\n\n /* ----------- NX via both file-lock and Redis NX ------------ */\n let result: string | null;\n if (effectiveTtl && effectiveTtl > 0) {\n result = await client.set(storageKey, this.serialize(value), { PX: effectiveTtl, NX: nx });\n } else {\n result = await client.set(storageKey, this.serialize(value), { NX: nx });\n }\n\n if (result !== 'OK') {\n const storedValue = await client.get(storageKey);\n if (storedValue === this.serialize(value)) {\n // ghost success\n return true;\n }\n return false;\n }\n\n return result === 'OK';\n }\n\n public async get(key: string): Promise<unknown> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const raw = await client.get(storageKey);\n return this.deserialize(raw);\n }\n\n public async del(key: string): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const storageKeyGroup = this.prefixKeyGroup(key);\n await client.del(storageKey);\n await client.del(storageKeyGroup);\n }\n\n public async has(key: string): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const exists = await client.exists(storageKey);\n if (exists === 0) return false;\n const raw = await client.get(storageKey);\n if (!raw) return false;\n const data = JSON.parse(raw) as { v: unknown; e: number | null };\n if (data.e && Date.now() > data.e) {\n await this.del(key);\n return false;\n }\n return true;\n }\n\n public async groupSet(key: string, subKey: string, value: unknown, { ttl }: { ttl?: number }): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n await client.hSet(storageKey, subKey, this.serialize(value));\n const effectiveTtl = ttl !== undefined ? ttl : this.defaultTtl;\n if (effectiveTtl > 0) {\n await client.expire(storageKey, Math.ceil(effectiveTtl / 1000));\n }\n }\n\n public async groupGet(key: string, subKey: string): Promise<unknown> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n const raw = await client.hGet(storageKey, subKey);\n return this.deserialize(raw);\n }\n\n public async groupHas(key: string, subKey: string): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n return (await client.hExists(storageKey, subKey)) === 1;\n }\n\n public async groupDel(key: string, subKey: string): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKeyGroup(key);\n await client.hDel(storageKey, subKey);\n }\n\n public async close(): Promise<void> {\n if (this.url && RedisAdapter.clients.has(this.url)) {\n const client = RedisAdapter.clients.get(this.url);\n if (client) {\n await client.quit();\n RedisAdapter.clients.delete(this.url);\n RedisAdapter.initPromises.delete(this.url);\n }\n }\n }\n\n public async flushAll(): Promise<void> {\n const client = this.getClient();\n await client.flushAll();\n }\n\n /**\n * 获取 LRU 缓存统计信息(Redis 不使用 LRU 缓存)\n */\n public getLruCacheStats(): { size: number; groupCount: number; maxSize: number } | null {\n return null;\n }\n}\n","/* eslint-disable no-await-in-loop */\n/* eslint-disable no-constant-condition */\n// eslint-disable-next-line no-promise-executor-return\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\ninterface WithRetryOptions {\n /** 最大重试次数 */\n max?: number;\n /** 初始退避时长,单位 ms */\n backoffBase?: number;\n /** 每次重试时的指数倍数 */\n backoffExponent?: number;\n /** 抖动范围,0~backoffJitter 毫秒 */\n backoffJitter?: number;\n /** 判断是否需要重试的函数 */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n needRetry?: (err: any) => boolean;\n}\n\n// 通用指数退避重试\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n {\n max = 15,\n backoffBase = 200,\n backoffExponent = 1.1,\n backoffJitter = 100,\n needRetry = () => true,\n // eslint-disable-next-line @typescript-eslint/comma-dangle\n }: WithRetryOptions = {}\n): Promise<T> {\n let attempt = 0;\n\n while (true) {\n try {\n return await fn();\n } catch (err) {\n // 超过最大重试次数或不需要重试,抛出错误\n if (!needRetry(err) || ++attempt > max) {\n throw err;\n }\n\n // 计算指数退避延迟:base * exponent^(attempt-1)\n const exp = backoffExponent ** (attempt - 1);\n const expDelay = backoffBase * exp;\n // 加上随机抖动\n const jitter = Math.random() * backoffJitter;\n const waitTime = Math.floor(expDelay + jitter);\n\n // 等待后重试\n await sleep(waitTime);\n }\n }\n}\n","/* eslint-disable prettier/prettier */\n/* eslint-disable max-classes-per-file */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// @ts-expect-error - event-hub 没有类型定义\nimport * as eventHubCluster from '@arcblock/event-hub';\n// @ts-expect-error - event-hub 没有类型定义\nimport * as eventHubSingle from '@arcblock/event-hub/single';\nimport { LRUCache } from 'lru-cache';\n\nconst isTestEnv = process.env.NODE_ENV === 'test';\n\n// 根据环境选择 event-hub 版本:测试环境使用单进程版本,生产环境使用集群版本\nconst eventHub = isTestEnv ? eventHubSingle : eventHubCluster;\n\nconst LRU_CACHE_SYNC_EVENT = 'db-cache:lru:sync';\nconst LRU_CACHE_DELETE_EVENT = 'db-cache:lru:delete';\nconst LRU_CACHE_CLEAR_EVENT = 'db-cache:lru:clear';\n\ninterface CacheEntry {\n value: string;\n expiresAt: number | null;\n}\n\n// LRU 缓存实例类型\ntype LRUCacheInstance = LRUCache<string, CacheEntry>;\n\ninterface SyncEventPayload {\n channel: string;\n key: string;\n value: string;\n expiresAt: number | null;\n isGroup?: boolean;\n subKey?: string;\n}\n\ninterface DeleteEventPayload {\n channel: string;\n keys: string[];\n isGroup?: boolean;\n groupKey?: string;\n}\n\ninterface ClearEventPayload {\n channel: string;\n}\n\n/**\n * 判断是否需要跨 worker 同步\n * - 测试环境不需要同步\n * - 非 cluster 模式(NODE_APP_INSTANCE 未定义)不需要同步\n */\nconst shouldEnableSync = (): boolean => {\n if (isTestEnv) {\n return false;\n }\n // NODE_APP_INSTANCE 由 PM2 在 cluster 模式下设置\n return process.env.NODE_APP_INSTANCE !== undefined;\n};\n\nexport interface LruCacheOptions {\n /** 缓存前缀,用于区分不同的缓存实例 */\n prefix: string;\n /** 最大缓存条数,默认 10000 */\n maxSize?: number;\n /** 是否启用跨 worker 同步,默认 true(在支持的环境中) */\n enableSync?: boolean;\n}\n\n/**\n * LRU 内存缓存工具类\n *\n * 特点:\n * 1. 基于 LRU 算法的内存缓存\n * 2. 支持 TTL 过期\n * 3. 支持 Node.js 集群模式下的跨 worker 同步\n * 4. 可单独使用,也可作为 Redis/SQLite 适配器的 L1 缓存层\n *\n * CLUSTER MODE NOTE:\n * 当运行在 cluster 模式下时,缓存数据会通过 event hub 广播给所有 worker,\n * 确保所有 worker 的内存缓存数据一致。\n */\nexport class LruCache {\n private static caches: Map<string, LRUCacheInstance> = new Map();\n\n private static groupCaches: Map<string, Map<string, LRUCacheInstance>> = new Map();\n\n private static listenerSetup: Map<string, boolean> = new Map();\n\n private cacheKey: string;\n\n private maxSize: number;\n\n private enableSync: boolean;\n\n constructor(options: LruCacheOptions) {\n this.cacheKey = `lru:${options.prefix}`;\n this.maxSize = options.maxSize ?? 10000;\n this.enableSync = (options.enableSync ?? true) && shouldEnableSync();\n\n if (!LruCache.caches.has(this.cacheKey)) {\n LruCache.caches.set(\n this.cacheKey,\n new LRUCache({\n max: this.maxSize,\n ttl: 0, // 我们自己管理 TTL\n })\n );\n LruCache.groupCaches.set(this.cacheKey, new Map());\n\n // 设置同步监听器\n if (this.enableSync && !LruCache.listenerSetup.has(this.cacheKey)) {\n this._setupSyncListener();\n LruCache.listenerSetup.set(this.cacheKey, true);\n }\n }\n }\n\n private getCache(): LRUCacheInstance {\n const cache = LruCache.caches.get(this.cacheKey);\n if (!cache) {\n throw new Error('LRU cache not initialized');\n }\n return cache;\n }\n\n private getGroupCaches(): Map<string, LRUCacheInstance> {\n const groupCaches = LruCache.groupCaches.get(this.cacheKey);\n if (!groupCaches) {\n throw new Error('LRU group cache not initialized');\n }\n return groupCaches;\n }\n\n private getOrCreateGroupCache(key: string): LRUCacheInstance {\n const groupCaches = this.getGroupCaches();\n if (!groupCaches.has(key)) {\n groupCaches.set(\n key,\n new LRUCache({\n max: this.maxSize,\n ttl: 0,\n })\n );\n }\n return groupCaches.get(key)!;\n }\n\n /**\n * 设置同步监听器,接收其他 worker 广播的缓存数据\n */\n private _setupSyncListener(): void {\n const { cacheKey, maxSize } = this;\n\n eventHub.on(LRU_CACHE_SYNC_EVENT, (payload: SyncEventPayload) => {\n const { channel, key, value, expiresAt, isGroup, subKey } = payload;\n if (channel !== cacheKey) return;\n\n const entry: CacheEntry = { value, expiresAt };\n\n if (isGroup && subKey !== undefined) {\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n const groupCache = groupCaches.get(key) || new LRUCache({ max: maxSize, ttl: 0 });\n groupCache.set(subKey, entry);\n groupCaches.set(key, groupCache);\n }\n } else {\n const cache = LruCache.caches.get(cacheKey);\n if (cache) {\n cache.set(key, entry);\n }\n }\n });\n\n eventHub.on(LRU_CACHE_DELETE_EVENT, (payload: DeleteEventPayload) => {\n const { channel, keys, isGroup, groupKey } = payload;\n if (channel !== cacheKey) return;\n\n if (isGroup && groupKey !== undefined) {\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n const groupCache = groupCaches.get(groupKey);\n if (groupCache) {\n for (const key of keys) {\n groupCache.delete(key);\n }\n }\n }\n } else {\n const cache = LruCache.caches.get(cacheKey);\n if (cache) {\n for (const key of keys) {\n cache.delete(key);\n // 同时删除相关的 group cache\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n groupCaches.delete(key);\n }\n }\n }\n }\n });\n\n eventHub.on(LRU_CACHE_CLEAR_EVENT, (payload: ClearEventPayload) => {\n const { channel } = payload;\n if (channel !== cacheKey) return;\n\n const cache = LruCache.caches.get(cacheKey);\n if (cache) {\n cache.clear();\n }\n const groupCaches = LruCache.groupCaches.get(cacheKey);\n if (groupCaches) {\n groupCaches.clear();\n }\n });\n }\n\n /**\n * 广播缓存数据给其他 worker\n */\n private _broadcastSync(key: string, value: string, expiresAt: number | null, isGroup = false, subKey?: string): void {\n if (this.enableSync) {\n eventHub.broadcast(LRU_CACHE_SYNC_EVENT, {\n channel: this.cacheKey,\n key,\n value,\n expiresAt,\n isGroup,\n subKey,\n });\n }\n }\n\n /**\n * 广播删除缓存给其他 worker\n */\n private _broadcastDelete(keys: string[], isGroup = false, groupKey?: string): void {\n if (this.enableSync && keys.length > 0) {\n eventHub.broadcast(LRU_CACHE_DELETE_EVENT, {\n channel: this.cacheKey,\n keys,\n isGroup,\n groupKey,\n });\n }\n }\n\n /**\n * 广播清空缓存给其他 worker\n */\n private _broadcastClear(): void {\n if (this.enableSync) {\n eventHub.broadcast(LRU_CACHE_CLEAR_EVENT, {\n channel: this.cacheKey,\n });\n }\n }\n\n private isExpired(entry: CacheEntry | undefined): boolean {\n if (!entry) return true;\n if (entry.expiresAt !== null && Date.now() > entry.expiresAt) {\n return true;\n }\n return false;\n }\n\n /* ---------------------- 基础 API ---------------------- */\n\n /**\n * 设置缓存\n * @param key 缓存键\n * @param value 序列化后的值\n * @param expiresAt 过期时间戳,null 表示永不过期\n */\n set(key: string, value: string, expiresAt: number | null): void {\n const cache = this.getCache();\n const entry: CacheEntry = { value, expiresAt };\n cache.set(key, entry);\n this._broadcastSync(key, value, expiresAt);\n }\n\n /**\n * 获取缓存\n * @param key 缓存键\n * @returns 序列化的值,未命中或过期返回 null\n */\n get(key: string): string | null {\n const cache = this.getCache();\n const entry = cache.get(key) as CacheEntry | undefined;\n\n if (!entry) return null;\n if (this.isExpired(entry)) {\n cache.delete(key);\n return null;\n }\n\n return entry.value;\n }\n\n /**\n * 检查缓存是否存在且未过期\n */\n has(key: string): boolean {\n const cache = this.getCache();\n const entry = cache.get(key) as CacheEntry | undefined;\n\n if (!entry) return false;\n if (this.isExpired(entry)) {\n cache.delete(key);\n return false;\n }\n\n return true;\n }\n\n /**\n * 删除缓存\n */\n del(key: string): void {\n const cache = this.getCache();\n cache.delete(key);\n\n // 同时删除相关的 group cache\n const groupCaches = this.getGroupCaches();\n groupCaches.delete(key);\n\n this._broadcastDelete([key]);\n }\n\n /**\n * 按前缀删除缓存\n * @returns 删除的数量\n */\n delByPrefix(prefix: string): number {\n const cache = this.getCache();\n const deletedKeys: string[] = [];\n\n for (const key of cache.keys()) {\n if ((key as string).startsWith(prefix)) {\n cache.delete(key);\n deletedKeys.push(key as string);\n }\n }\n\n // 同时删除匹配前缀的 group caches\n const groupCaches = this.getGroupCaches();\n for (const key of groupCaches.keys()) {\n if (key.startsWith(prefix)) {\n groupCaches.delete(key);\n }\n }\n\n this._broadcastDelete(deletedKeys);\n return deletedKeys.length;\n }\n\n /* ---------------------- 分组 API ---------------------- */\n\n /**\n * 设置分组缓存\n */\n groupSet(key: string, subKey: string, value: string, expiresAt: number | null): void {\n const groupCache = this.getOrCreateGroupCache(key);\n const entry: CacheEntry = { value, expiresAt };\n groupCache.set(subKey, entry);\n this._broadcastSync(key, value, expiresAt, true, subKey);\n }\n\n /**\n * 获取分组缓存\n */\n groupGet(key: string, subKey: string): string | null {\n const groupCaches = this.getGroupCaches();\n const groupCache = groupCaches.get(key);\n\n if (!groupCache) return null;\n\n const entry = groupCache.get(subKey) as CacheEntry | undefined;\n if (!entry) return null;\n if (this.isExpired(entry)) {\n groupCache.delete(subKey);\n return null;\n }\n\n return entry.value;\n }\n\n /**\n * 检查分组缓存是否存在\n */\n groupHas(key: string, subKey: string): boolean {\n const groupCaches = this.getGroupCaches();\n const groupCache = groupCaches.get(key);\n\n if (!groupCache) return false;\n\n const entry = groupCache.get(subKey) as CacheEntry | undefined;\n if (!entry) return false;\n if (this.isExpired(entry)) {\n groupCache.delete(subKey);\n return false;\n }\n\n return true;\n }\n\n /**\n * 删除分组缓存\n */\n groupDel(key: string, subKey: string): void {\n const groupCaches = this.getGroupCaches();\n const groupCache = groupCaches.get(key);\n\n if (groupCache) {\n groupCache.delete(subKey);\n this._broadcastDelete([subKey], true, key);\n }\n }\n\n /* ---------------------- 管理 API ---------------------- */\n\n /**\n * 清空所有缓存\n */\n clear(): void {\n const cache = this.getCache();\n cache.clear();\n\n const groupCaches = this.getGroupCaches();\n groupCaches.clear();\n\n this._broadcastClear();\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): { size: number; groupCount: number; maxSize: number } {\n const cache = this.getCache();\n const groupCaches = this.getGroupCaches();\n\n let totalGroupSize = 0;\n for (const groupCache of groupCaches.values()) {\n totalGroupSize += groupCache.size;\n }\n\n return {\n size: cache.size, // 普通缓存条目数\n groupCount: totalGroupSize, // 分组缓存条目数\n maxSize: this.maxSize, // 最大容量\n };\n }\n\n /**\n * 关闭缓存(清理资源)\n *\n * 注意:不会广播 close 事件给其他 worker,因为每个 worker 有独立的生命周期\n */\n close(): void {\n // 移除 event listeners(避免内存泄漏)\n // 注意:eventHub 可能没有提供 off 方法,这取决于具体实现\n // 如果没有 off 方法,listeners 会在进程结束时自动清理\n\n LruCache.caches.delete(this.cacheKey);\n LruCache.groupCaches.delete(this.cacheKey);\n LruCache.listenerSetup.delete(this.cacheKey);\n }\n}\n","/* eslint-disable require-await */\n/* eslint-disable prettier/prettier */\n/* eslint-disable no-promise-executor-return */\n/* eslint-disable max-classes-per-file */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable @typescript-eslint/comma-dangle */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { promisify } from 'node:util';\nimport sqlite3, { type Database } from 'sqlite3';\nimport { withRetry } from '../with-retry';\nimport type { BaseDBCacheParams, IDBAdapter } from './adapter';\nimport { LruCache } from '../lru-cache';\n\nconst retryOptions = {\n needRetry: (err: Error) => err.message?.includes('SQLITE_BUSY') || err.message?.includes('disk I/O'),\n};\n\nconst dbRun = (db: sqlite3.Database, sql: string, params?: unknown[]) => {\n return withRetry(() => {\n return new Promise<void>((res, rej) => {\n db.run(sql, params, (err: Error | null) => (err ? rej(err) : res()));\n });\n }, retryOptions);\n};\n\nconst dbExec = (db: sqlite3.Database, sql: string) => {\n return withRetry(() => {\n return new Promise<void>((res, rej) => {\n db.exec(sql, (err: Error | null) => (err ? rej(err) : res()));\n });\n }, retryOptions);\n};\n\nconst dbGet = <T>(db: sqlite3.Database, sql: string, params?: unknown[]) => {\n return withRetry(() => {\n return new Promise<T>((res, rej) => {\n db.get(sql, params, (err: Error | null, result: unknown) => (err ? rej(err) : res(result as T)));\n });\n }, retryOptions);\n};\n\nasync function initSqliteWithRetry(db: sqlite3.Database) {\n db.configure('busyTimeout', 5000);\n\n try {\n await dbExec(\n db,\n `\n PRAGMA journal_mode = WAL;\n PRAGMA synchronous = normal;\n PRAGMA wal_autocheckpoint = 5000;\n PRAGMA busy_timeout = 5000;\n `\n );\n\n await dbRun(\n db,\n `\n CREATE TABLE IF NOT EXISTS kvcache (\n key TEXT NOT NULL,\n subKey TEXT NOT NULL,\n value TEXT NOT NULL,\n expiresAt INTEGER,\n PRIMARY KEY (key, subKey)\n )\n `\n );\n } catch (err) {\n throw new Error(`SQLite init failed: ${err}`);\n }\n}\n\nexport class SqliteAdapter implements IDBAdapter {\n public opts: BaseDBCacheParams = null as unknown as BaseDBCacheParams;\n\n private static clients: Map<string, Database> = new Map();\n\n private static initPromises: Map<string, Promise<void>> = new Map();\n\n private static cleanupTimers: Map<string, NodeJS.Timeout> = new Map();\n\n private static lruCaches: Map<string, LruCache> = new Map();\n\n /** LRU 缓存的最大条数上限 */\n private static readonly MAX_LRU_CACHE_SIZE = 100;\n\n public prefix: string = '';\n\n public defaultTtl: number = 1000 * 60 * 60;\n\n private cleanupInterval: number = 5 * 60 * 1000;\n\n private dbPath: string = '';\n\n private enableLruCache: boolean = false;\n\n private lruCache: LruCache | null = null;\n\n /* ------------------------------- init ------------------------------- */\n\n public async ensure(): Promise<void> {\n const isMemory = this.opts.sqlitePath === ':memory:';\n if (!this.dbPath) {\n this.dbPath = isMemory ? ':memory:' : path.resolve(this.opts.sqlitePath);\n this.prefix = this.opts.prefix;\n this.defaultTtl = this.opts.ttl;\n this.cleanupInterval = this.opts.cleanupInterval ?? 5 * 60 * 1000;\n this.enableLruCache = this.opts.enableLruCache ?? false;\n }\n\n // 初始化 LRU 缓存层\n if (this.enableLruCache && !this.lruCache) {\n const lruCacheKey = `sqlite:${this.dbPath}:${this.prefix}`;\n if (!SqliteAdapter.lruCaches.has(lruCacheKey)) {\n const requestedSize = this.opts.lruMaxSize ?? 100;\n const actualSize = Math.min(requestedSize, SqliteAdapter.MAX_LRU_CACHE_SIZE);\n\n if (requestedSize > SqliteAdapter.MAX_LRU_CACHE_SIZE) {\n console.warn(\n `[SqliteAdapter] Requested LRU cache size ${requestedSize} exceeds maximum ${SqliteAdapter.MAX_LRU_CACHE_SIZE}, using ${actualSize} instead`\n );\n }\n\n SqliteAdapter.lruCaches.set(\n lruCacheKey,\n new LruCache({\n prefix: lruCacheKey,\n maxSize: actualSize,\n enableSync: this.opts.enableSync ?? true,\n })\n );\n }\n this.lruCache = SqliteAdapter.lruCaches.get(lruCacheKey)!;\n }\n\n if (SqliteAdapter.clients.has(this.dbPath)) return;\n\n if (!SqliteAdapter.initPromises.has(this.dbPath)) {\n if (!isMemory) {\n const dir = path.dirname(this.dbPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n }\n\n SqliteAdapter.initPromises.set(\n this.dbPath,\n (async () => {\n const db = new sqlite3.Database(this.dbPath);\n await initSqliteWithRetry(db);\n\n SqliteAdapter.clients.set(this.dbPath, db);\n SqliteAdapter.cleanupTimers.set(\n this.dbPath,\n setInterval(\n () => {\n this.cleanup().catch(console.error);\n },\n this.cleanupInterval + Math.random() * 30000\n )\n );\n })()\n );\n }\n\n await SqliteAdapter.initPromises.get(this.dbPath);\n }\n\n private getClient(): Database {\n if (!this.dbPath || !SqliteAdapter.clients.has(this.dbPath)) {\n throw new Error('SQLite not initialized');\n }\n return SqliteAdapter.clients.get(this.dbPath)!;\n }\n\n /* ------------------------------- cleanup ------------------------------- */\n\n private async cleanup(): Promise<void> {\n const client = this.getClient();\n await dbRun(client, 'DELETE FROM kvcache WHERE expiresAt IS NOT NULL AND expiresAt <= ?', [Date.now()]);\n }\n\n /* ------------------------------- core ------------------------------- */\n\n private prefixKey(key: string): string {\n return `${this.prefix}:${key}`;\n }\n\n public serialize(value: unknown): string {\n return JSON.stringify({ v: value });\n }\n\n public deserialize(raw: string | null | undefined): unknown {\n if (raw === null || raw === undefined) return null;\n try {\n return (JSON.parse(raw) as { v: unknown }).v;\n } catch {\n return null;\n }\n }\n\n public async set(key: string, value: unknown, opts: { ttl?: number; nx?: boolean }): Promise<boolean> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : null;\n const serializedValue = this.serialize(value);\n\n // 对于 NX 选项,先检查 key 是否存在\n if (opts.nx) {\n // 先检查 L1 缓存\n if (this.lruCache?.has(storageKey)) {\n return false;\n }\n // 再检查 L2 数据库\n const existing = await dbGet<{ value: string }>(\n client,\n 'SELECT value FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, '']\n );\n if (existing) {\n return false;\n }\n }\n\n // 写入 L2 数据库\n await dbRun(\n client,\n `\n INSERT INTO kvcache (key, subKey, value, expiresAt)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(key, subKey) DO UPDATE SET\n value = excluded.value,\n expiresAt = excluded.expiresAt\n `,\n [storageKey, '', serializedValue, expiresAt]\n );\n\n // 写入 L1 缓存\n if (this.lruCache) {\n this.lruCache.set(storageKey, serializedValue, expiresAt);\n }\n\n return true;\n }\n\n public async get(key: string): Promise<unknown> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache) {\n const cached = this.lruCache.get(storageKey);\n if (cached !== null) {\n return this.deserialize(cached);\n }\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ value: string; expiresAt: number | null }>(\n client,\n 'SELECT value, \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, '']\n );\n\n if (!row) return null;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.del(key);\n return null;\n }\n\n // 写入 L1 缓存(回填)\n if (this.lruCache) {\n this.lruCache.set(storageKey, row.value, row.expiresAt);\n }\n\n return this.deserialize(row.value);\n }\n\n public async del(key: string): Promise<void> {\n const storageKey = this.prefixKey(key);\n\n // 删除 L1 缓存\n if (this.lruCache) {\n this.lruCache.del(storageKey);\n }\n\n // 删除 L2 数据库\n const client = this.getClient();\n await dbRun(client, 'DELETE FROM kvcache WHERE key = ?', [storageKey]);\n }\n\n public async has(key: string): Promise<boolean> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache?.has(storageKey)) {\n return true;\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ expiresAt: number | null }>(\n client,\n 'SELECT \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, '']\n );\n\n if (!row) return false;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.del(key);\n return false;\n }\n\n return true;\n }\n\n /* ------------------------------- group APIs ------------------------------- */\n\n public async groupSet(\n key: string,\n subKey: string,\n value: unknown,\n opts: { ttl?: number; nx?: boolean }\n ): Promise<void> {\n const client = this.getClient();\n const storageKey = this.prefixKey(key);\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : null;\n const serializedValue = this.serialize(value);\n\n // 写入 L2 数据库(UPSERT)\n await dbRun(\n client,\n `\n INSERT INTO kvcache (key, subKey, value, expiresAt)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(key, subKey) DO UPDATE SET\n value = excluded.value,\n expiresAt = excluded.expiresAt\n `,\n [storageKey, subKey, serializedValue, expiresAt]\n );\n\n // 写入 L1 缓存\n if (this.lruCache) {\n this.lruCache.groupSet(storageKey, subKey, serializedValue, expiresAt);\n }\n }\n\n public async groupGet(key: string, subKey: string): Promise<unknown> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache) {\n const cached = this.lruCache.groupGet(storageKey, subKey);\n if (cached !== null) {\n return this.deserialize(cached);\n }\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ value: string; expiresAt: number | null }>(\n client,\n 'SELECT value, \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, subKey]\n );\n\n if (!row) return null;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.groupDel(key, subKey);\n return null;\n }\n\n // 写入 L1 缓存(回填)\n if (this.lruCache) {\n this.lruCache.groupSet(storageKey, subKey, row.value, row.expiresAt);\n }\n\n return this.deserialize(row.value);\n }\n\n public async groupHas(key: string, subKey: string): Promise<boolean> {\n const storageKey = this.prefixKey(key);\n\n // 先查 L1 缓存\n if (this.lruCache?.groupHas(storageKey, subKey)) {\n return true;\n }\n\n // L1 未命中,查 L2 数据库\n const client = this.getClient();\n const row = await dbGet<{ expiresAt: number | null }>(\n client,\n 'SELECT \"expiresAt\" FROM kvcache WHERE key = ? AND subKey = ?',\n [storageKey, subKey]\n );\n\n if (!row) return false;\n if (row.expiresAt !== null && Date.now() > row.expiresAt) {\n await this.groupDel(key, subKey);\n return false;\n }\n\n return true;\n }\n\n public async groupDel(key: string, subKey: string): Promise<void> {\n const storageKey = this.prefixKey(key);\n\n // 删除 L1 缓存\n if (this.lruCache) {\n this.lruCache.groupDel(storageKey, subKey);\n }\n\n // 删除 L2 数据库\n const client = this.getClient();\n await dbRun(client, 'DELETE FROM kvcache WHERE key = ? AND subKey = ?', [storageKey, subKey]);\n }\n\n /* ------------------------------- misc ------------------------------- */\n\n public async close(): Promise<void> {\n // 关闭 LRU 缓存\n if (this.lruCache) {\n this.lruCache.close();\n const lruCacheKey = `sqlite:${this.dbPath}:${this.prefix}`;\n SqliteAdapter.lruCaches.delete(lruCacheKey);\n this.lruCache = null;\n }\n\n if (this.dbPath) {\n const timer = SqliteAdapter.cleanupTimers.get(this.dbPath);\n if (timer) {\n clearInterval(timer);\n SqliteAdapter.cleanupTimers.delete(this.dbPath);\n }\n\n const client = SqliteAdapter.clients.get(this.dbPath);\n if (client) {\n client.close();\n SqliteAdapter.clients.delete(this.dbPath);\n SqliteAdapter.initPromises.delete(this.dbPath);\n }\n }\n }\n\n public async flushAll(): Promise<void> {\n // 清空 L1 缓存\n if (this.lruCache) {\n this.lruCache.clear();\n }\n\n // 清空 L2 数据库\n const client = this.getClient();\n const run = promisify(client.run.bind(client));\n await run('DELETE FROM kvcache');\n }\n\n /**\n * 获取 LRU 缓存统计信息\n */\n public getLruCacheStats(): { size: number; groupCount: number; maxSize: number } | null {\n if (!this.lruCache) {\n return null;\n }\n return this.lruCache.getStats();\n }\n}\n","/* eslint-disable prettier/prettier */\n// base-db-cache.ts\nimport { RedisAdapter } from './adapter/redis-adapter';\nimport { SqliteAdapter } from './adapter/sqlite-adapter';\nimport { BaseDBCacheOptions, IDBAdapter } from './adapter/adapter';\n\nexport class BaseDBCache {\n private adapter: IDBAdapter = null as unknown as IDBAdapter;\n\n public prefix: string = '';\n\n public type: string = '';\n\n public defaultTtl: number = 0;\n\n private getOpts: BaseDBCacheOptions;\n\n private _initdAdapter: boolean = false;\n\n constructor(opts: BaseDBCacheOptions) {\n this.getOpts = opts;\n }\n\n protected initAdapter(): void {\n if (this._initdAdapter) {\n return;\n }\n\n\n if (typeof this.getOpts !== 'function') {\n throw new Error('getOpts must be a function');\n }\n\n const opts = this.getOpts();\n\n if (!opts.prefix || typeof opts.prefix !== 'string' || opts.prefix.trim() === '') {\n throw new Error('prefix is required');\n }\n if (!opts.sqlitePath || typeof opts.sqlitePath !== 'string') {\n throw new Error('sqlitePath is required');\n }\n if (typeof opts.ttl !== 'number' || opts.ttl < 0) {\n throw new Error('ttl must be a non-negative number');\n }\n\n if (opts.cleanupInterval && opts.cleanupInterval < 1000 * 60 * 5) {\n console.error('cleanupInterval must be at least 5 minutes');\n throw new Error('cleanupInterval must be at least 5 minutes');\n }\n\n this.type = opts.forceType || (opts.redisUrl ? 'redis' : 'sqlite');\n\n this.prefix = opts.prefix;\n this.defaultTtl = opts.ttl;\n\n switch (this.type) {\n case 'redis':\n this.adapter = new RedisAdapter();\n this.adapter.opts = opts;\n break;\n case 'sqlite':\n this.adapter = new SqliteAdapter();\n this.adapter.opts = opts;\n break;\n default:\n throw new Error(`Unsupported backend: ${this.type}`);\n }\n\n this._initdAdapter = true;\n\n }\n\n static randomKey(): string {\n return Math.random().toString(36).substring(2, 15);\n }\n\n public async set(key: string, value: unknown, opts: { ttl?: number; nx?: boolean } = {}): Promise<boolean> {\n this.initAdapter();\n\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve(false);\n }\n // Determine TTL: provided or default\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n if (typeof effectiveTtl !== 'number' || effectiveTtl < 0) {\n console.error('ttl must be a non-negative number');\n throw new Error('ttl must be a non-negative number');\n }\n await this.adapter.ensure();\n return this.adapter.set(key, value, { ttl: effectiveTtl, nx: opts.nx });\n }\n\n public async get(key: string): Promise<unknown> {\n this.initAdapter();\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve();\n }\n\n await this.adapter.ensure();\n return this.adapter.get(key);\n }\n\n public async del(key: string): Promise<void> {\n this.initAdapter();\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve();\n }\n await this.adapter.ensure();\n return this.adapter.del(key);\n }\n\n public async has(key: string): Promise<boolean> {\n this.initAdapter();\n\n if (typeof key !== 'string') {\n console.error('key must be a string');\n return Promise.resolve(false);\n }\n await this.adapter.ensure();\n return this.adapter.has(key);\n }\n\n public async groupSet(\n key: string,\n subKey: string,\n value: unknown,\n opts: { ttl?: number; nx?: boolean } = {},\n ): Promise<void> {\n this.initAdapter();\n\n if (typeof key !== 'string' || typeof subKey !== 'string') {\n return Promise.resolve();\n }\n // Determine TTL: provided or default\n const effectiveTtl = opts.ttl !== undefined ? opts.ttl : this.defaultTtl;\n if (typeof effectiveTtl !== 'number' || effectiveTtl < 0) {\n console.error('ttl must be a non-negative number');\n throw new Error('ttl must be a non-negative number');\n }\n await this.adapter.ensure();\n return this.adapter.groupSet(key, subKey, value, { ttl: effectiveTtl, nx: opts.nx });\n }\n\n public async groupGet(key: string, subKey: string): Promise<unknown> {\n this.initAdapter();\n\n if (typeof key !== 'string' || typeof subKey !== 'string') {\n console.error('key must be a string');\n return null;\n }\n await this.adapter.ensure();\n return this.adapter.groupGet(key, subKey);\n }\n\n public async groupHas(key: string, subKey: string): Promise<boolean> {\n this.initAdapter();\n\n if (typeof key !== 'string') {\n throw new Error('key must be a string');\n }\n if (typeof subKey !== 'string') {\n throw new Error('subKey must be a string');\n }\n\n await this.adapter.ensure();\n return this.adapter.groupHas(key, subKey);\n }\n\n public async groupDel(key: string, subKey: string): Promise<void> {\n this.initAdapter();\n\n if (!key || !subKey) {\n return Promise.resolve();\n }\n await this.adapter.ensure();\n\n return this.adapter.groupDel(key, subKey);\n }\n\n public async close(): Promise<void> {\n this.initAdapter();\n\n await this.adapter.ensure();\n\n return this.adapter.close();\n }\n\n public async flushAll(): Promise<void> {\n this.initAdapter();\n await this.adapter.ensure();\n return this.adapter.flushAll();\n }\n\n /**\n * 获取 LRU 缓存统计信息\n * @returns 缓存统计信息,如果未启用 LRU 缓存则返回 null\n */\n public getLruCacheStats(): { size: number; groupCount: number; maxSize: number } | null {\n this.initAdapter();\n return this.adapter.getLruCacheStats();\n }\n}\n","/* eslint-disable prettier/prettier */\nimport { BaseDBCache } from './base-db-cache';\nimport { BaseDBCacheOptions } from './adapter/adapter';\n\nexport default class SingleFlightDBCache extends BaseDBCache {\n private _pending: Map<string, Promise<unknown>>;\n\n constructor(opts: BaseDBCacheOptions) {\n super(opts);\n this._pending = new Map<string, Promise<unknown>>();\n }\n\n /**\n * If a request for the same key is already in flight, reuse it.\n * Otherwise, fetch, cache, and return the value.\n */\n public autoCache<T>(key: string, fn: () => Promise<T>, { ttl }: { ttl?: number } = {}): Promise<T> {\n this.initAdapter();\n // Treat empty key as bypassing cache\n if (!key) {\n return fn();\n }\n\n if (typeof key !== 'string') {\n throw new Error('key must be a string');\n }\n\n if (this._pending.has(key)) {\n return this._pending.get(key) as Promise<T>;\n }\n\n const task = (async (): Promise<T> => {\n try {\n const hit = (await super.get(key)) as T | null;\n if (hit !== null) {\n return hit;\n }\n const result = await fn();\n await super.set(key, result, { ttl });\n return result;\n } finally {\n this._pending.delete(key);\n }\n })();\n\n this._pending.set(key, task);\n return task;\n }\n\n /**\n * Same logic as autoCache, but for group fields (hash).\n */\n public autoCacheGroup<T>(\n key: string,\n subKey: string,\n fn: () => Promise<T>,\n { ttl }: { ttl?: number } = {},\n ): Promise<T> {\n this.initAdapter();\n // Treat missing key or subKey as bypass\n if (!key || !subKey) {\n return fn();\n }\n\n if (typeof key !== 'string') {\n throw new Error('key must be a string');\n }\n\n if (typeof subKey !== 'string') {\n throw new Error('subKey must be a string');\n }\n\n const pendingKey = `${key}-${subKey}`;\n if (this._pending.has(pendingKey)) {\n return this._pending.get(pendingKey) as Promise<T>;\n }\n\n const task = (async (): Promise<T> => {\n try {\n const hit = (await super.groupGet(key, subKey)) as T | null;\n if (hit !== null) {\n return hit;\n }\n const result = await fn();\n await super.groupSet(key, subKey, result, { ttl });\n return result;\n } finally {\n this._pending.delete(pendingKey);\n }\n })();\n\n this._pending.set(pendingKey, task);\n return task;\n }\n}\n","/* eslint-disable no-await-in-loop */\nimport { ulid } from '../tools/ulid';\nimport SingleFlightDBCache from './single-flight-db-cache';\n\nexport default class LockDBCache extends SingleFlightDBCache {\n private _inFlight: Map<string, number> = new Map();\n\n public async createLock(lockName: string): Promise<boolean> {\n this.initAdapter();\n if (!lockName) {\n return false;\n }\n const key = this._formatLockKey(lockName);\n\n // 如果本地标记已经在进行\"抢锁\"操作,直接返回 false\n // 注意:这只是本地优化,真正的锁在 Redis/SQLite 中\n const lastLockTime = this._inFlight.get(key);\n if (lastLockTime && Date.now() - lastLockTime < this.defaultTtl) {\n return false;\n }\n\n // 标记正在抢锁\n this._inFlight.set(key, Date.now());\n\n try {\n // 直接使用 SET NX 原子操作来获取锁,不需要先检查再设置\n // SET key value NX PX ttl 是原子操作:\n // - 如果 key 不存在,设置成功并返回 \"OK\"\n // - 如果 key 已存在,不设置并返回 null\n // 这样可以避免 Check-Then-Act 竞态条件\n const result = await this.set(key, ulid(), { ttl: this.defaultTtl, nx: true });\n return result;\n } finally {\n // 无论成功或失败,一定要把 inFlight 标记删除\n this._inFlight.delete(key);\n // 清空过期时间\n for (const [key2, value] of this._inFlight.entries()) {\n if (Date.now() - value > this.defaultTtl) {\n this._inFlight.delete(key2);\n }\n }\n }\n }\n\n /**\n * 检查锁是否已经过期:只要缓存层面已经没有该 key,就代表已过期或从未创建。\n *\n * @param lockName 锁的名称\n * @returns 如果锁不存在或已过期,返回 true;否则返回 false\n */\n public async hasExpired(lockName: string): Promise<boolean> {\n this.initAdapter();\n if (!lockName) {\n return true;\n }\n const key = this._formatLockKey(lockName);\n const exists = await this.has(key);\n return !exists;\n }\n\n /**\n * 主动释放锁:删除对应的缓存 key\n *\n * @param lockName 锁的名称\n */\n public async releaseLock(lockName: string): Promise<void> {\n this.initAdapter();\n if (!lockName) {\n return;\n }\n const key = this._formatLockKey(lockName);\n await this.del(key);\n }\n\n /**\n * 等待锁释放或超时。每隔 100ms 检查一次缓存层面是否仍存在该锁 key。\n * 如果在 timeoutMs 毫秒内 key 不再存在,则 resolve(true)。否则 resolve(false)。\n *\n * @param lockName 锁的名称\n * @param timeoutMs 等待超时时间(毫秒),默认使用构造时传入的 this._timeout\n * @returns 如果锁被释放或过期,resolve(true);等待到超时还没释放,则 resolve(false)\n */\n // eslint-disable-next-line require-await\n public async waitUnLock(lockName: string, timeoutMs: number = this.defaultTtl): Promise<boolean> {\n this.initAdapter();\n\n if (!lockName) {\n return true;\n }\n const key = this._formatLockKey(lockName);\n const start = Date.now();\n\n return new Promise((resolve) => {\n const interval = setInterval(async () => {\n const exists = await this.has(key);\n if (!exists) {\n clearInterval(interval);\n resolve(true);\n } else if (Date.now() - start >= timeoutMs) {\n clearInterval(interval);\n resolve(false);\n }\n // 否则继续等待\n }, 100);\n });\n }\n\n /**\n * 获取锁的流程:\n * 1. 先尝试 createLock(lockName):\n * - 如果立刻拿到(createLock 返回 true),直接返回;\n * - 如果没拿到,就等待 waitUnLock(lockName)。\n * 2. 等待到释放/过期后,再次尝试 createLock(lockName)。\n *\n * @param lockName 锁的名称\n */\n public async acquire(lockName: string): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const acquired = await this.createLock(lockName);\n if (acquired) {\n return;\n }\n await this.waitUnLock(lockName);\n }\n }\n\n private _formatLockKey(lockName: string): string {\n return `lock:${this.prefix}:${lockName}`;\n }\n}\n","import path from 'path';\nimport { BaseDBCacheParams } from './adapter/adapter';\nimport DBCache from './lock-db-cache';\nimport { withRetry } from './with-retry';\nimport { LruCache } from './lru-cache';\n\nexport type { BaseDBCacheOptions, IDBAdapter, ForceType } from './adapter/adapter';\nexport { LruCache };\n\nconst isJestTest = () => {\n return process.env.NODE_ENV === 'test' || process.env.BABEL_ENV === 'test';\n};\n\nexport const getAbtNodeRedisAndSQLiteUrl = () => {\n const blockletCacheDir = process.env.BLOCKLET_DATA_DIR\n ? path.join(process.env.BLOCKLET_DATA_DIR, '__default-cache-store.db')\n : undefined;\n const params = {\n redisUrl: process.env.ABT_NODE_CACHE_REDIS_URL,\n sqlitePath: isJestTest() ? ':memory:' : blockletCacheDir || process.env.ABT_NODE_CACHE_SQLITE_PATH,\n };\n if (process.env.ABT_NODE_NO_CACHE === 'true') {\n (params as unknown as BaseDBCacheParams).ttl = 1;\n }\n return params;\n};\n\nexport { DBCache, withRetry };\n"],"names":["__publicField","path"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abtnode/db-cache",
|
|
3
|
-
"version": "1.17.8-beta-
|
|
3
|
+
"version": "1.17.8-beta-20260121-102603-f9d0176f",
|
|
4
4
|
"description": "Db cache use redis, sqlite or memory as backend",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"prettier": "^3.3.2",
|
|
45
45
|
"unbuild": "^2.0.0"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "7ae816f51ed511037e5b7ac0008012ebf4afc987"
|
|
48
48
|
}
|