feat(cache): PG kv_cache ported from MP TTLCache, TMDB request and recognize caches
Migration 0042_cache adds UNLOGGED kv_cache. PgCache mirrors MP
runtime/cache.py (region, per-key TTL, TLRU maxsize eviction, @cached as
cachedCall); only the storage moves from memory to PG. TMDB request
responses (MP TMDb.request @cached) and recognize results (MP TmdbCache:
same key, {id:0} negative cache with EMPTY_RESULT_CACHE_TTL, type-conflict
checks, backfill after manual assignment) live in kv_cache, shared by all
processes. Settings cache.tmdbTtlHours / tmdbMaxSize / emptyResultTtlSec
map to META_CACHE_EXPIRE / CONF.tmdb / EMPTY_RESULT_CACHE_TTL. TMDB
details now also store posterPath / backdropPath.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
61f585a707
commit
946fca5e55
22 files changed
+743
-14
No files matched your search
@@ -24,6 +24,16 @@ const CacheShape = z.object({
|
||||
checkIntervalSec: z.number().int().min(10).max(3600),
|
||||
/** 缓存清理的目标使用率(低水位) */
|
||||
cleanupTargetPercent: Percent,
|
||||
/** TMDB 缓存(请求响应 + 识别结果)保留小时数(对照 MP META_CACHE_EXPIRE,缺省 24) */
|
||||
tmdbTtlHours: z.number().int().min(1).max(720),
|
||||
/** TMDB 缓存每类条数上限,超出删最旧(对照 MP CONF.tmdb,缺省 256;大内存模式 1024) */
|
||||
tmdbMaxSize: z.number().int().min(16).max(100_000),
|
||||
/** 空结果 / 未识别的短缓存秒数(对照 MP EMPTY_RESULT_CACHE_TTL,缺省 1800) */
|
||||
emptyResultTtlSec: z.number().int().min(0).max(86_400),
|
||||
/** 图片代理落盘缓存(对照 MP GLOBAL_IMAGE_CACHE,缺省关闭;关闭时仍代理,只是不落盘) */
|
||||
globalImageCache: z.boolean(),
|
||||
/** 图片缓存保留天数,超过即清理(对照 MP GLOBAL_IMAGE_CACHE_DAYS,缺省 7) */
|
||||
globalImageCacheDays: z.number().int().min(1).max(3650),
|
||||
});
|
||||
/** 下载缓存卷硬阈值与恢复水位(REQ §8.4.1) */
|
||||
export const CacheSettings = CacheShape.refine((v) => v.resumePercent < v.hardThresholdPercent, {
|
||||
@@ -330,7 +340,17 @@ export type SettingsKey = z.infer<typeof SettingsKey>;
|
||||
/** 缺省设置(settings 表缺 key 或缺字段时使用) */
|
||||
export const DEFAULT_SETTINGS: GlobalSettings = {
|
||||
automation: { enabled: true, readOnlyReconcile: false },
|
||||
cache: { hardThresholdPercent: 90, resumePercent: 85, checkIntervalSec: 60, cleanupTargetPercent: 80 },
|
||||
cache: {
|
||||
hardThresholdPercent: 90,
|
||||
resumePercent: 85,
|
||||
checkIntervalSec: 60,
|
||||
cleanupTargetPercent: 80,
|
||||
tmdbTtlHours: 24,
|
||||
tmdbMaxSize: 256,
|
||||
emptyResultTtlSec: 1800,
|
||||
globalImageCache: false,
|
||||
globalImageCacheDays: 7,
|
||||
},
|
||||
organize: { defaultMode: "copy", allowCrossVolumeMove: true, minSizeBytes: 50 * 1024 * 1024 },
|
||||
retention: { seedRetentionDays: 7, logRetentionDays: 180 },
|
||||
pi: {
|
||||
@@ -587,10 +607,22 @@ export const SETTINGS_SECTIONS: readonly SettingsSectionDef[] = [
|
||||
{
|
||||
id: "metadata",
|
||||
label: "元数据",
|
||||
description: "TMDB API Key 与地址",
|
||||
description: "TMDB API Key 与地址、TMDB 缓存、图片代理",
|
||||
legacyTabs: [],
|
||||
anchors: [{ id: "tmdb", label: "TMDB" }],
|
||||
fields: ["metadata.tmdbApiKeySecretRef", "metadata.tmdbBaseUrl"],
|
||||
anchors: [
|
||||
{ id: "tmdb", label: "TMDB" },
|
||||
{ id: "tmdb-cache", label: "TMDB 缓存" },
|
||||
{ id: "images", label: "图片代理与缓存" },
|
||||
],
|
||||
fields: [
|
||||
"metadata.tmdbApiKeySecretRef",
|
||||
"metadata.tmdbBaseUrl",
|
||||
"cache.tmdbTtlHours",
|
||||
"cache.tmdbMaxSize",
|
||||
"cache.emptyResultTtlSec",
|
||||
"cache.globalImageCache",
|
||||
"cache.globalImageCacheDays",
|
||||
],
|
||||
resources: [],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user