feat(cache): capacity LRU for image cache (CACHE-2)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
85b352b8eb
commit
d13c18b4b1
3 files changed
+186
-22
No files matched your search
+23
-2
@@ -12,7 +12,7 @@ import type { z } from "zod";
|
||||
import { dataPaths } from "../../config.ts";
|
||||
import { requireScope } from "../../http/auth.ts";
|
||||
import { errorBody } from "../../http/errors.ts";
|
||||
import { CACHE_REGIONS, sharedCache, tmdbCachePolicy } from "../../shared-cache.ts";
|
||||
import { CACHE_REGIONS, sharedCache, storageSettings, tmdbCachePolicy } from "../../shared-cache.ts";
|
||||
import { registerScheduledJob } from "../schedules/registry.ts";
|
||||
import type { ModuleApp, ServerContext, ServerModule } from "../types.ts";
|
||||
import { ImageCache, ImageProxyError } from "./images.ts";
|
||||
@@ -22,7 +22,8 @@ import { ImageCache, ImageProxyError } from "./images.ts";
|
||||
* - PG 缓存 kv_cache(UNLOGGED,移植 MP TTLCache)的过期行物理清理任务 cache.sweep(每 10 分钟);
|
||||
* - TMDB 缓存管理(对照 MP tmdb_cache_items / tmdb_cache_clear):GET /cache/tmdb、POST /cache/tmdb/clear;
|
||||
* - 图片代理 GET /img/tmdb/{size}/{file}(会话或 API Key read,移植 MP ImageHelper / fetch_image)+ DATA_DIR/cache/images 落盘,
|
||||
* 用量 / 清空 GET /cache/images、POST /cache/images/clear,按保留天数清理的任务 cache.images_clean(每天)。
|
||||
* 用量 / 清空 GET /cache/images、POST /cache/images/clear,按保留天数清理的任务 cache.images_clean(每天);
|
||||
* - CACHE-2:图片缓存容量 LRU 任务 cache.images_lru(30 分钟,预算 storage.budgets.imagesGb,超出删最久未访问)。
|
||||
*/
|
||||
export interface CacheModuleOptions {
|
||||
/** 图片上游 fetch(测试注入) */
|
||||
@@ -203,6 +204,26 @@ export function createCacheModule(opts: CacheModuleOptions = {}): ServerModule &
|
||||
return { summary: `删除 ${n} 张过期图片` };
|
||||
},
|
||||
});
|
||||
registerScheduledJob(ctx, {
|
||||
key: "cache.images_lru",
|
||||
defaults: {
|
||||
name: "图片缓存容量控制",
|
||||
description: "图片代理缓存超过容量预算(存储设置,缺省 20 GB)时,按最久未访问删除到预算的 90%",
|
||||
group: "maintain",
|
||||
schedule: { type: "interval", everyMs: 30 * 60_000 },
|
||||
firstRun: "after_interval",
|
||||
},
|
||||
run: async () => {
|
||||
const { imagesGb } = (await storageSettings(ctx)).budgets;
|
||||
const r = await images(ctx).enforceBudget(Math.round(imagesGb * 1024 ** 3));
|
||||
const gb = (b: number) => `${Math.round((b / 1024 ** 3) * 100) / 100} GB`;
|
||||
return {
|
||||
summary: r.deleted
|
||||
? `删除 ${r.deleted} 张最久未访问的图片,释放 ${gb(r.freedBytes)},现用 ${gb(r.usedBytes)}`
|
||||
: `现用 ${gb(r.usedBytes)},未超过预算 ${imagesGb} GB`,
|
||||
};
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user