Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.

perf(tui): cache overview summaries between data updates - #184

Merged
makoMakoGo merged 6 commits into
personal/local-clientsfrom
codex/overview-summary-cache
Jul 22, 2026
Merged

perf(tui): cache overview summaries between data updates#184
makoMakoGo merged 6 commits into
personal/local-clientsfrom
codex/overview-summary-cache

Conversation

@makoMakoGo

@makoMakoGo makoMakoGo commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • derive a stable, theme-independent OverviewSummary whenever the installed usage projection changes
  • keep selected main-session counts in the same replacement lifecycle, including local client and grouping projections
  • render the Overview snapshot from cached aggregates and collapse portrait artwork to borrowed row spans with static padding

Motivation

The snapshot introduced in #183 rebuilt model, client, and family aggregates from every daily record on each render tick. It also split static portrait rows into per-character String allocations. This follow-up moves data-dependent work to projection installation while leaving layout, theme mapping, and ticker animation in the renderer.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --locked --workspace --all-targets --all-features -- -D warnings
  • cargo test --locked --workspace --all-features

Summary by CodeRabbit

  • 新功能
    • 概览页新增更完整的使用汇总:缓存命中率、活跃天数、峰值数据、模型与客户端数量等。
    • 展示最常用的模型、客户端以及模型家族“最爱”。
  • 体验改进
    • 切换本地/投影数据后,概览与排行自动同步更新,排序更一致。
    • 缓存命中率相关的阶梯/成就计算口径更统一。
    • 冷启动/冷失败时页脚状态更简洁,加载提示更清晰。
    • 模型家族头像/颜色与版式对齐更稳定。

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@makoMakoGo, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bae224b7-9a56-40b1-ba2a-13ab1407fbd0

📥 Commits

Reviewing files that changed from the base of the PR and between 0b1b9b1 and 336a98e.

📒 Files selected for processing (1)
  • crates/tokscale-cli/src/tui/data/overview.rs

Walkthrough

概览数据现在由 OverviewSummary 统一聚合并由 App 维护,Overview 页面、成就和肖像直接使用该汇总;同时移除 UsageData.loading,简化冷启动加载与页脚状态渲染。

Changes

概览汇总与 TUI 渲染

Layer / File(s) Summary
概览聚合模型
crates/tokscale-cli/src/tui/data/*
新增模型家族、缓存比例、汇总指标及稳定 favorite 排名逻辑,并补充测试。
App 汇总状态生命周期
crates/tokscale-cli/src/tui/app.rs
App 初始化、数据替换和 TUI 快照安装时同步维护 overview_summary,并根据已选来源更新主会话数量。
Overview 快照渲染迁移
crates/tokscale-cli/src/tui/ui/overview_snapshot.rs
各 Overview 面板改为直接读取 OverviewSummary,使用预聚合指标、favorite 信息和客户端数量。
家族肖像与成就适配
crates/tokscale-cli/src/tui/ui/portraits.rs, crates/tokscale-cli/src/tui/ui/achievements.rs
共享 OverviewFamilyCacheRate,并调整肖像宽度填充和缓存成就阈值判断。
冷启动与 UsageData 契约
crates/tokscale-core/src/usage_views.rs, crates/tokscale-cli/src/tui/ui/*, crates/tokscale-cli/src/tui/cache.rs
移除 UsageData.loading 和 spinner 模块,统一冷启动文案、状态判断及相关测试。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant UsageData
  participant App
  participant OverviewSummary
  participant OverviewSnapshot
  UsageData->>App: 提供初始化或更新后的使用数据
  App->>OverviewSummary: derive(data, main_session_count)
  OverviewSummary-->>App: 返回汇总指标与 favorite
  App->>OverviewSnapshot: overview_summary()
  OverviewSnapshot-->>App: 渲染概览页面
Loading

Possibly related PRs

Poem

小兔捧起汇总表,
家族模型排成行。
App 更新不迷路,
Overview 闪着光。
冷启动文案轻轻唱,
兔耳随风摇呀摇。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.96% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了本次变更的核心:在 TUI 数据更新间缓存概览汇总以提升性能。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/overview-summary-cache

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codspeed-hq

codspeed-hq Bot commented Jul 21, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 43 untouched benchmarks


Comparing codex/overview-summary-cache (336a98e) with personal/local-clients (385c71a)

Open in CodSpeed

Derive snapshot aggregates when report projections are installed or replaced. Keep render ticks free of daily map rebuilds and per-character portrait allocations.
Derive one decimal-place cache rate in the Overview summary and use it for rendering, fun facts, and achievement thresholds.
Enforce a three-row portrait contract and compose full, compact, and minimal layouts without index-based slicing.
Derive cold loading and failure from installed-generation state, keep their diagnostics out of the footer, and remove the unused UsageData loading flag.
Use the shared token formatter for input-health and fun-fact counts instead of maintaining a duplicate implementation.
@makoMakoGo
makoMakoGo force-pushed the codex/overview-summary-cache branch from 877eb86 to 0b1b9b1 Compare July 22, 2026 00:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/tokscale-cli/src/tui/ui/footer.rs (1)

222-241: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Overview 页脚计数仍在每帧重新遍历 daily 数据,绕过了新增的 OverviewSummary 缓存。

current_count_label 针对 Tab::Overview 的分支在每次渲染时都会重新遍历 app.data.daily → client_breakdown → models 来统计 distinct 的 model/client 数量,而这与 crates/tokscale-cli/src/tui/data/overview.rsOverviewSummary::derive 的遍历逻辑完全重复,后者已经在投影安装时算好了 model_count/client_count 并被缓存。本 PR 的目标正是"仅在安装的报告投影变化时重建汇总,terminal ticks/resize/主题切换都不应重新折叠 daily 数据",而页脚这里恰恰在每次 tick 都重新做了这个折叠,抵消了缓存收益。

建议直接复用 app.overview_summary() 已计算好的字段:

♻️ 建议的修复
 fn current_count_label(app: &App) -> String {
     match app.current_tab {
         Tab::Overview => {
-            let mut models = BTreeSet::new();
-            let mut clients = BTreeSet::new();
-            for day in &app.data.daily {
-                for (client, client_info) in &day.client_breakdown {
-                    clients.insert(client.as_str());
-                    for model in client_info.models.values() {
-                        models.insert(model.model_id.as_str());
-                    }
-                }
-            }
+            let summary = app.overview_summary();
             format!(
                 " ({} models · {} clients · {} days)",
-                models.len(),
-                clients.len(),
+                summary.model_count,
+                summary.client_count,
                 app.data.daily.len()
             )
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-cli/src/tui/ui/footer.rs` around lines 222 - 241, 更新
current_count_label 的 Tab::Overview 分支,移除对 app.data.daily、client_breakdown 和
models 的重复遍历,改为复用 app.overview_summary() 中已缓存的 model_count 和 client_count
字段;保留现有 days 数量及标签格式。
crates/tokscale-cli/src/tui/ui/overview_snapshot.rs (1)

173-215: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

None 分支未对 portrait/slogan 做居中处理,与 Some 分支视觉不一致

Some 分支所有内容都经过 center_line 处理,但 None(无 favorite family,如零使用量)分支的 portraitslogan 均未调用 center_line,渲染时会左对齐而非居中,与 portraits::lines 的文档约定(调用方需自行对每行做居中)不符。

🐛 建议修复
         None => {
-            portrait = portraits::lines(app, OverviewFamily::Unknown);
-            slogan = Some(Line::from(Span::styled(
-                "no data yet",
-                Style::default().fg(app.theme.muted),
-            )));
+            portrait = portraits::lines(app, OverviewFamily::Unknown)
+                .map(|line| center_line(line, width));
+            slogan = Some(center_line(
+                Line::from(Span::styled(
+                    "no data yet",
+                    Style::default().fg(app.theme.muted),
+                )),
+                width,
+            ));
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-cli/src/tui/ui/overview_snapshot.rs` around lines 173 - 215,
Update the None branch of the favorite_family match to apply center_line to the
Unknown portrait lines and the “no data yet” slogan, using the existing width
value; keep the current styling and Some-branch behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/tokscale-cli/src/tui/ui/footer.rs`:
- Around line 222-241: 更新 current_count_label 的 Tab::Overview 分支,移除对
app.data.daily、client_breakdown 和 models 的重复遍历,改为复用 app.overview_summary() 中已缓存的
model_count 和 client_count 字段;保留现有 days 数量及标签格式。

In `@crates/tokscale-cli/src/tui/ui/overview_snapshot.rs`:
- Around line 173-215: Update the None branch of the favorite_family match to
apply center_line to the Unknown portrait lines and the “no data yet” slogan,
using the existing width value; keep the current styling and Some-branch
behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6b141da3-dfce-49b2-8563-f806df1a63f9

📥 Commits

Reviewing files that changed from the base of the PR and between 877eb86 and 0b1b9b1.

📒 Files selected for processing (14)
  • crates/tokscale-cli/src/tui/app.rs
  • crates/tokscale-cli/src/tui/cache.rs
  • crates/tokscale-cli/src/tui/data/mod.rs
  • crates/tokscale-cli/src/tui/data/overview.rs
  • crates/tokscale-cli/src/tui/ui/achievements.rs
  • crates/tokscale-cli/src/tui/ui/footer.rs
  • crates/tokscale-cli/src/tui/ui/loading.rs
  • crates/tokscale-cli/src/tui/ui/mod.rs
  • crates/tokscale-cli/src/tui/ui/overview_snapshot.rs
  • crates/tokscale-cli/src/tui/ui/portraits.rs
  • crates/tokscale-cli/src/tui/ui/spinner.rs
  • crates/tokscale-core/src/aggregate/parity_tests.rs
  • crates/tokscale-core/src/aggregate/tui.rs
  • crates/tokscale-core/src/usage_views.rs
💤 Files with no reviewable changes (4)
  • crates/tokscale-cli/src/tui/ui/spinner.rs
  • crates/tokscale-core/src/usage_views.rs
  • crates/tokscale-core/src/aggregate/parity_tests.rs
  • crates/tokscale-core/src/aggregate/tui.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/tokscale-cli/src/tui/data/mod.rs
  • crates/tokscale-cli/src/tui/app.rs

Exercise cache-read and cache-write token buckets through OverviewSummary::derive so the rendered cache rate cannot silently use the wrong aggregate.
@makoMakoGo
makoMakoGo merged commit a3c890b into personal/local-clients Jul 22, 2026
8 checks passed
@makoMakoGo
makoMakoGo deleted the codex/overview-summary-cache branch July 22, 2026 01:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant