fix(lifecycle): 「元数据已刷新」事件改在 refreshMetadata 内与刷新同事务发出,覆盖语言回刷与剧集组切换;下一轮待办完成后移出计划
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
6d37a337c9
commit
155f30417c
4 files changed
+11
-15
No files matched your search
@@ -26,7 +26,7 @@ export async function emitMediaWatched(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 作品元数据刷新完成(刷新任务的调用方发;按任务 run 去重) */
|
/** 作品元数据刷新完成(refreshMetadata 内发;runId 传本次刷新时间,按次去重) */
|
||||||
export async function emitMetadataRefreshed(
|
export async function emitMetadataRefreshed(
|
||||||
ctx: Pick<ServerContext, "outbox">,
|
ctx: Pick<ServerContext, "outbox">,
|
||||||
exec: Exec,
|
exec: Exec,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { type Actor, audit, type Exec } from "./common.ts";
|
|||||||
import { resolveEntityId, seedAliases } from "./entities.ts";
|
import { resolveEntityId, seedAliases } from "./entities.ts";
|
||||||
import { reresolveEntityEpisodes } from "./episode-resolution.ts";
|
import { reresolveEntityEpisodes } from "./episode-resolution.ts";
|
||||||
import { entityEpisodeGroup, groupLayout, type Layout, relayoutUnits } from "./episode-structure.ts";
|
import { entityEpisodeGroup, groupLayout, type Layout, relayoutUnits } from "./episode-structure.ts";
|
||||||
|
import { emitMetadataRefreshed } from "./lifecycle-events.ts";
|
||||||
import {
|
import {
|
||||||
applySeasonMetadata,
|
applySeasonMetadata,
|
||||||
metadataIncludeSpecials,
|
metadataIncludeSpecials,
|
||||||
@@ -423,6 +424,13 @@ export async function refreshMetadata(
|
|||||||
await trx.updateTable("media_entity").set({ last_metadata_refresh_at: now }).where("id", "=", id).execute();
|
await trx.updateTable("media_entity").set({ last_metadata_refresh_at: now }).where("id", "=", id).execute();
|
||||||
// 季总集数 / 播出日期 / 完结状态更新后重算待确认与滞后放行的资源(raw / 换算过的资源不受只升的总集数影响)
|
// 季总集数 / 播出日期 / 完结状态更新后重算待确认与滞后放行的资源(raw / 换算过的资源不受只升的总集数影响)
|
||||||
if (ident.entity_type === "tv") await reresolveEntityEpisodes(ctx, trx, id, { onlyPending: true });
|
if (ident.entity_type === "tv") await reresolveEntityEpisodes(ctx, trx, id, { onlyPending: true });
|
||||||
|
// 生命周期广播(ADR-006):元数据已刷新——所有刷新入口(刷新任务、语言回刷、剧集组切换)统一在这里发,与刷新同事务
|
||||||
|
await emitMetadataRefreshed(ctx, trx, {
|
||||||
|
mediaEntityId: id,
|
||||||
|
full: !!opts.full,
|
||||||
|
changedFields: r.changedFields,
|
||||||
|
runId: now.toISOString(),
|
||||||
|
});
|
||||||
const promoted = episodes.reduce((n, x) => n + x.promoted, 0);
|
const promoted = episodes.reduce((n, x) => n + x.promoted, 0);
|
||||||
return {
|
return {
|
||||||
status: "refreshed" as const,
|
status: "refreshed" as const,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import type { SourcesRuntime } from "./runtime.ts";
|
|||||||
import { refreshSiteAccount } from "./service/account.ts";
|
import { refreshSiteAccount } from "./service/account.ts";
|
||||||
import { AUTO_ENRICH_TASK, runAutoEnrich } from "./service/enrich.ts";
|
import { AUTO_ENRICH_TASK, runAutoEnrich } from "./service/enrich.ts";
|
||||||
import { ingestFeed } from "./service/feeds.ts";
|
import { ingestFeed } from "./service/feeds.ts";
|
||||||
import { emitMetadataRefreshed } from "./service/lifecycle-events.ts";
|
|
||||||
import { refreshMetadata } from "./service/metadata.ts";
|
import { refreshMetadata } from "./service/metadata.ts";
|
||||||
import { prewarmMetadata } from "./service/metadata-prewarm.ts";
|
import { prewarmMetadata } from "./service/metadata-prewarm.ts";
|
||||||
import { resolveRelease } from "./service/resolve.ts";
|
import { resolveRelease } from "./service/resolve.ts";
|
||||||
@@ -78,16 +77,8 @@ export function registerSourcesTasks(registry: TaskRegistry, rt: () => SourcesRu
|
|||||||
retryPolicy: NETWORK_RETRY,
|
retryPolicy: NETWORK_RETRY,
|
||||||
handler: (t) =>
|
handler: (t) =>
|
||||||
t.step.run("refresh", async () => {
|
t.step.run("refresh", async () => {
|
||||||
const r = await refreshMetadata(rt(), t.input.mediaEntityId, { full: !!t.input.full });
|
// 「元数据已刷新」生命周期事件在 refreshMetadata 内与刷新同事务发出
|
||||||
// 生命周期广播(ADR-006):元数据已刷新(在调用方发,刷新本身在 metadata.ts)
|
return await refreshMetadata(rt(), t.input.mediaEntityId, { full: !!t.input.full });
|
||||||
if (r.status === "refreshed")
|
|
||||||
await emitMetadataRefreshed(rt().ctx, rt().ctx.db, {
|
|
||||||
mediaEntityId: t.input.mediaEntityId,
|
|
||||||
full: !!t.input.full,
|
|
||||||
changedFields: r.changedFields,
|
|
||||||
runId: t.runId,
|
|
||||||
});
|
|
||||||
return r;
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
// 关注作品预热(统一元数据缓存):详情 / 各季 / 剧集组 / 图片先进缓存;网络道,走 TMDB 客户端限流
|
// 关注作品预热(统一元数据缓存):详情 / 各季 / 剧集组 / 图片先进缓存;网络道,走 TMDB 客户端限流
|
||||||
|
|||||||
@@ -31,9 +31,6 @@
|
|||||||
|
|
||||||
### 进行中
|
### 进行中
|
||||||
|
|
||||||
- 下一轮(界面第二轮合并后):
|
|
||||||
- 统一元数据缓存:TMDB / 豆瓣 / Bangumi 共用「来源 × 资源类型」TTL 策略;进程内存一级 + PG `kv_cache` 二级,LISTEN/NOTIFY 跨进程失效;过期先用旧值后台刷新;关注中作品续期不淘汰、进入关注时预热(各季、剧集组、图片);同请求合并;按 region 统计命中率。刮削顺带接 TMDB `logos` 写 `clearlogo.png`。fanart.tv 暂不接(用户 2026-10-06 定)。
|
|
||||||
- 生命周期事件与功能模块约定:广播事件 + 链式钩子(参考 MoviePilot EventType / ChainEventType),功能清单给智能体,前端插槽默认显示、不做开关;补字幕迁为样板。
|
|
||||||
- 系统梳理后的待办:[system-review.md](system-review.md),T0~T6 按优先级。
|
- 系统梳理后的待办:[system-review.md](system-review.md),T0~T6 按优先级。
|
||||||
- 补字幕:[subtitles.md](subtitles.md),第 1、2 步已完成;待办:以后接进整理 / 订阅工作流。
|
- 补字幕:[subtitles.md](subtitles.md),第 1、2 步已完成;待办:以后接进整理 / 订阅工作流。
|
||||||
- 沙箱第二批:站点网页、RSS、网页抓取的 HTML / XML 解析迁入常驻子进程池(ADR-005)。
|
- 沙箱第二批:站点网页、RSS、网页抓取的 HTML / XML 解析迁入常驻子进程池(ADR-005)。
|
||||||
|
|||||||
Reference in new issue
Block a user