perf: cache public gallery views
This commit is contained in:
@@ -243,6 +243,7 @@ npm run check:server-rs-ddd
|
||||
|
||||
- Rust 结构体:`BigFishCreationSession`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/big_fish/tables.rs`
|
||||
- 索引:`by_big_fish_session_owner_user_id`、`by_big_fish_session_stage`。公开广场 view 使用 `by_big_fish_session_stage` 读取已发布会话,避免扫整表。
|
||||
|
||||
### `big_fish_event`
|
||||
|
||||
@@ -254,6 +255,13 @@ npm run check:server-rs-ddd
|
||||
- Rust 结构体:`BigFishRuntimeRun`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/big_fish/tables.rs`
|
||||
|
||||
### SpacetimeDB view:`big_fish_gallery_view`
|
||||
|
||||
- Rust view:`big_fish_gallery_view`
|
||||
- 返回类型:`Vec<BigFishWorkSummarySnapshot>`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/big_fish/session.rs`
|
||||
- 说明:大鱼吃小鱼公开广场列表投影,只从 `Published` creation session 组装公开卡片字段;`api-server` 的 `spacetime-client` 长期订阅 `SELECT * FROM big_fish_gallery_view` 与 `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'big-fish'` 后,从本地 cache 构造 `/api/runtime/big-fish/gallery` 响应。公开列表不再每个 HTTP 请求调用 `list_big_fish_works` procedure;个人作品列表、详情、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
||||
|
||||
### `chapter_progression`
|
||||
|
||||
- Rust 结构体:`ChapterProgression`
|
||||
@@ -340,6 +348,13 @@ npm run check:server-rs-ddd
|
||||
- Rust 结构体:`Match3DWorkProfileRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/match3d/tables.rs`
|
||||
|
||||
### SpacetimeDB view:`match_3_d_gallery_view`
|
||||
|
||||
- Rust view:`match3d_gallery_view`
|
||||
- 返回类型:`Vec<Match3DGalleryViewRow>`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/match3d/mod.rs`
|
||||
- 说明:抓大鹅公开广场列表投影,只暴露 `publication_status = published` 的作品卡片字段;`api-server` 的 `spacetime-client` 长期订阅 `SELECT * FROM match_3_d_gallery_view` 与 `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'match3d'` 后,从本地 cache 构造 `/api/runtime/match3d/gallery` 响应。公开列表不再每个 HTTP 请求调用 `list_match3d_works` procedure;个人作品列表、详情、发布、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
||||
|
||||
### `npc_state`
|
||||
|
||||
- Rust 结构体:`NpcState`
|
||||
@@ -479,14 +494,24 @@ npm run check:server-rs-ddd
|
||||
|
||||
- `SELECT * FROM puzzle_gallery_view`
|
||||
- `SELECT * FROM custom_world_gallery_entry`
|
||||
- `SELECT * FROM match_3_d_gallery_view`
|
||||
- `SELECT * FROM square_hole_gallery_view`
|
||||
- `SELECT * FROM visual_novel_gallery_view`
|
||||
- `SELECT * FROM big_fish_gallery_view`
|
||||
|
||||
下列订阅用于统计或配置缓存,订阅失败不会让公开列表连接整体不可用,调用方保留兼容兜底:
|
||||
|
||||
- `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'puzzle'`
|
||||
- `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'custom-world'`
|
||||
- `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'match3d'`
|
||||
- `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'square-hole'`
|
||||
- `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'visual-novel'`
|
||||
- `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'big-fish'`
|
||||
- `SELECT * FROM creation_entry_config`
|
||||
- `SELECT * FROM creation_entry_type_config`
|
||||
|
||||
拼图、自定义世界、抓大鹅、方洞挑战、视觉小说和大鱼吃小鱼的公开列表 HTTP 路由都从订阅 cache 读取公开 read model / view。各玩法的个人作品列表、详情、发布、点赞、游玩记录、Remix 和其它需要鉴权或写入副作用的路径继续走 procedure / reducer;不要为了公开列表性能把这些 owner-specific 或 mutation 语义混进 public view。
|
||||
|
||||
`GET /api/creation-entry/config` 和入口熔断优先从订阅 cache 读取创作入口配置;cache 缺失时使用最近一次成功读取的内存快照,再兜底调用 `get_creation_entry_config` procedure 完成空库种子或旧库兼容。
|
||||
|
||||
未来可选:若发现页、推荐流和各玩法广场需要统一给浏览器前端直接订阅公开作品列表,只新增 / 统一专用 public read model,例如 `public_work_gallery_entry`。该 read model 必须是后端投影后的公开作品卡片契约,覆盖作品类型、公开作品号、标题、摘要、封面、作者展示名、排序键、公开统计和入口开关后的可见性,不暴露玩法领域源表 row shape。前端可选择订阅这个稳定投影来减少 HTTP 拉取,但不能订阅 `puzzle_work_profile`、`custom_world_profile` 等源表后自行拼装列表;BFF 仍保留首屏、SEO / 分享、旧客户端、订阅失败和灰度期间的 HTTP fallback。
|
||||
@@ -536,6 +561,13 @@ npm run check:server-rs-ddd
|
||||
- Rust 结构体:`SquareHoleWorkProfileRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/square_hole/tables.rs`
|
||||
|
||||
### SpacetimeDB view:`square_hole_gallery_view`
|
||||
|
||||
- Rust view:`square_hole_gallery_view`
|
||||
- 返回类型:`Vec<SquareHoleGalleryViewRow>`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/square_hole/mod.rs`
|
||||
- 说明:方洞挑战公开广场列表投影,只暴露 `publication_status = published` 的作品卡片字段;`api-server` 的 `spacetime-client` 长期订阅 `SELECT * FROM square_hole_gallery_view` 与 `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'square-hole'` 后,从本地 cache 构造 `/api/runtime/square-hole/gallery` 响应。公开列表不再每个 HTTP 请求调用 `list_square_hole_works` procedure;个人作品列表、详情、发布、点赞、游玩记录和 Remix 仍按原有 procedure / reducer 路径处理。
|
||||
|
||||
### `story_event`
|
||||
|
||||
- Rust 结构体:`StoryEvent`
|
||||
@@ -600,3 +632,10 @@ npm run check:server-rs-ddd
|
||||
|
||||
- Rust 结构体:`VisualNovelWorkProfileRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/visual_novel.rs`
|
||||
|
||||
### SpacetimeDB view:`visual_novel_gallery_view`
|
||||
|
||||
- Rust view:`visual_novel_gallery_view`
|
||||
- 返回类型:`Vec<VisualNovelGalleryViewRow>`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/visual_novel.rs`
|
||||
- 说明:视觉小说公开广场列表投影,只暴露 `publication_status = published` 的作品卡片字段,不把完整 `draft` 暴露给公开列表订阅;`api-server` 的 `spacetime-client` 长期订阅 `SELECT * FROM visual_novel_gallery_view` 与 `SELECT * FROM public_work_play_daily_stat WHERE source_type = 'visual-novel'` 后,从本地 cache 构造 `/api/runtime/visual-novel/gallery` 响应。公开列表不再每个 HTTP 请求调用 `list_visual_novel_works` procedure;个人历史、详情、运行态和发布仍按原有 procedure / reducer 路径处理。
|
||||
|
||||
@@ -157,7 +157,7 @@ Jenkins 按 web / api / Spacetime module / build / deploy / publish 拆分
|
||||
- `genarrative-api.service` 设置 `LimitNOFILE=65535`、`TasksMax=2048`;上线后用 `systemctl show genarrative-api.service -p LimitNOFILE -p TasksMax` 和 `cat /proc/$(pidof api-server)/limits` 核对。
|
||||
- Nginx `/api/` 与 `/admin/api/` 通过 `genarrative_api` upstream 代理到 `127.0.0.1:8082`,upstream keepalive 为 64;压测时看 `/var/log/nginx/genarrative.access.log` 中的 `request_time`、`upstream_connect_time`、`upstream_header_time`、`upstream_response_time`、`upstream_status`、`request_id`。
|
||||
- 作品列表 K6 脚本一次 iteration 默认请求两个公开接口,因此约 50 HTTP req/s 的目标命令使用 `SCENARIO=spike START_RPS=5 PEAK_RPS=25 HOLD=60s END_RPS=5 DETAIL_RATIO=0 npm run loadtest:k6:works`。
|
||||
- 作品列表短期继续由 `api-server` / BFF 订阅 SpacetimeDB 公开 read model 后读本地 cache,不让浏览器前端直接订阅完整列表;未来如新增 `public_work_gallery_entry` 等专用公开作品列表 read model,前端只可订阅该稳定投影,不能订阅玩法源表后自行 join、聚合或判断权限。
|
||||
- 作品列表短期继续由 `api-server` / BFF 订阅 SpacetimeDB 公开 read model 后读本地 cache,不让浏览器前端直接订阅完整列表;未来如新增 `public_work_gallery_entry` 等专用公开作品列表 read model,前端只可订阅稳定、低基数、公开的专用投影,禁止订阅 `puzzle_work_profile`、`custom_world_profile` 等玩法源表后自行 join、聚合或判断权限。前端直订阅落地前必须先补齐权限、字段契约、排序 / 分页、埋点和 BFF 回退策略。
|
||||
- 50 HTTP req/s 验收目标为 `http_req_failed < 1%`、`p95 < 2s`、`dropped_iterations = 0`,同时压测窗口内 Nginx 无新增 502。
|
||||
|
||||
OpenTelemetry 现阶段可选 OTLP traces / metrics / logs,但本地日志与 Nginx 文件日志仍保留:
|
||||
|
||||
Reference in New Issue
Block a user