mirror of
https://github.com/hansjone/netx.git
synced 2026-10-11 23:20:52 +08:00
Fix business compare history, search, sampling and exports
This commit is contained in:
parent
afa8e06b2d
commit
4d5101ec3a
19 changed files with 1598 additions and 274 deletions
BIN
docs/reviews/assets/biz-compare-desktop.png
Normal file
BIN
docs/reviews/assets/biz-compare-desktop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
BIN
docs/reviews/assets/biz-compare-error.png
Normal file
BIN
docs/reviews/assets/biz-compare-error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
docs/reviews/assets/biz-compare-legacy.png
Normal file
BIN
docs/reviews/assets/biz-compare-legacy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
29
docs/reviews/assets/biz-compare-memory-benchmark.json
Normal file
29
docs/reviews/assets/biz-compare-memory-benchmark.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"date": "2026-10-10",
|
||||
"baseline_ref": "afa8e06b2de64100f963ae30b3babfcb5d7009f4",
|
||||
"python": "3.14.3",
|
||||
"dataset": {
|
||||
"rows_per_side": 1000000,
|
||||
"fields": ["id", "neighbor", "state", "afi"],
|
||||
"strata": 50,
|
||||
"unchanged_limit": 5000,
|
||||
"compact_unchanged": true,
|
||||
"interface_transforms": false,
|
||||
"all_rows_unchanged": true
|
||||
},
|
||||
"measurement": "tracemalloc peak allocated during compare_rows; excludes input allocations, DB loading and process overhead",
|
||||
"results": [
|
||||
{
|
||||
"engine": "baseline",
|
||||
"peak_engine_mib": 1144.43,
|
||||
"seconds_with_tracemalloc": 92.4
|
||||
},
|
||||
{
|
||||
"engine": "optimized",
|
||||
"peak_engine_mib": 420.49,
|
||||
"seconds_with_tracemalloc": 63.681
|
||||
}
|
||||
],
|
||||
"results_and_sample_order_identical": true,
|
||||
"test_result": "1 passed in 157.88s"
|
||||
}
|
||||
BIN
docs/reviews/assets/biz-compare-narrow.png
Normal file
BIN
docs/reviews/assets/biz-compare-narrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
120
docs/reviews/biz-compare-review-2026-10-10.md
Normal file
120
docs/reviews/biz-compare-review-2026-10-10.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# 业务对比检查与优化记录
|
||||
|
||||
检查日期:2026-10-10。范围:网络管理 → 割接对比 → 业务对比,包括前端任务/批次/结果界面、Python 与 PostgreSQL 对比路径、结果分页与搜索、短期列表缓存。
|
||||
|
||||
本次直接修改项目代码并添加回归测试,没有连接设备执行采集,也没有修改生产数据库。浏览器截图与交互测试使用固定 API 响应。
|
||||
|
||||
## 已修复的问题
|
||||
|
||||
### 1. 搜索会改变业务判定(P1)
|
||||
|
||||
原实现分别按搜索条件过滤割接前、后的原表,再重新对比。例如 `state=up → down`,搜索 `up` 后只剩前侧,原本的“变化”就可能变成“删除”。重复身份键的业务还可能在筛选后错位配对。
|
||||
|
||||
现在:已存储的判定直接在结果表分页筛选;需要回查未保存全量明细的成功行时,先找到候选身份键,再补齐两侧的完整分组,按原有配对规则对比,最后筛选。达到读取上限的分组整体跳过,并返回截断标记,避免产生虚假的新增或删除。
|
||||
|
||||
### 2. PostgreSQL 搜索漏用部分模板过滤条件(P1)
|
||||
|
||||
原搜索只下推 SQL 支持的过滤规则,对 `age_timer` 等不支持的规则直接忽略,可能将静态 ARP 等不属于模板范围的数据纳入结果。现在不支持下推的规则走流式读取并在 Python 中完整过滤。
|
||||
|
||||
### 3. 快速切换时旧请求覆盖当前任务(P1)
|
||||
|
||||
前后采集任务的批次列表、打开任务、加载历史结果以及轮询缺少完整的过期保护。现在对批次请求使用清理标记,对任务与结果使用请求序号;关闭弹窗、切换路由或打开其他任务后,旧响应不能覆盖当前界面。
|
||||
|
||||
### 4. 结果加载错误容易被误读(P2)
|
||||
|
||||
原查询失败时保留上一组明细,界面已经显示新筛选条件;切到未完成的表后,加载状态也可能无法结束。现在加载和失败都有独立状态,错误时清除旧明细并提供重试入口;切换表/页签后清理加载状态。
|
||||
|
||||
### 5. LLDP 搜索漏查(P2)
|
||||
|
||||
LLDP 数据存于 `biz_state_lldp_neighbor`,原搜索只读 `biz_state_metric_row`。现在原表回查与精简结果的字段搜索都支持 LLDP 表。
|
||||
|
||||
### 6. 其他已修复边界
|
||||
|
||||
- 恰好命中读取上限时,原非 PostgreSQL 路径错误地报告“已截断”;现在多读一条判断。
|
||||
- 无效或有歧义的表标识可能落到其他表;现在返回 `sheet_not_found`。
|
||||
- `%`、`_` 等搜索字符按字面值匹配,避免不同查询路径含义不一致。
|
||||
- 关闭最后一项检查后,空数组被解释为“启用全部”;现在阻止关闭最后一项并提示至少保留一项。
|
||||
- 两个 HeroUI Input 使用了 `isDisabled`,实际需要 `disabled`;过滤值与容差输入的禁用状态已修正。
|
||||
- 列表缓存缺少并发合并,慢请求可以覆盖强制刷新结果或在失效后重新填充缓存;现在共享请求、保护失效状态并抑制过期的后台通知。
|
||||
- 清理中英文文案中的重复键,解决相关类型检查错误。
|
||||
|
||||
## 性能改动与实际收益范围
|
||||
|
||||
- 合并两套轮询,下一轮在本轮请求完成后启动。模拟浏览器测试中,运行任务在 5.2 秒内请求历史列表和详情各两次,没有重复轮询,也不会因慢请求持续叠加。
|
||||
- 已保存的失败、新增、变化等结果在数据库中筛选并分页,避免每次翻页重新加载和对比原始批次。回归测试明确验证这一查询路径不调用 `compare_rows`。
|
||||
- 同一前后采集任务的批次请求共用短期缓存,列表后台刷新合并同一请求;6 项缓存测试覆盖并发、强制刷新、失败重试与失效竞态。
|
||||
- 模板查找使用 Map,避免列表搜索与绘制逐项线性查找模板。
|
||||
- 修改筛选后先回到第一页,避免先请求旧页码再重复请求第一页。
|
||||
|
||||
这些改动减少了重复工作。以下后续基准使用合成数据,没有测量生产环境延迟。
|
||||
|
||||
## 后续优化(2026-10-10)
|
||||
|
||||
### 历史执行配置与精简行还原
|
||||
|
||||
新运行在创建时将模板、启用的检查项、字段规则/过滤、接口归一化、端口映射、成功行保存策略和名称存入 `summary_json.config_snapshot`。后台执行、成功行回查、精简行还原以及导出共用该配置;排队之后修改配置,甚至删除原模板/映射,也不会改变这一运行使用的配置。无需数据库结构迁移。
|
||||
|
||||
修复了精简存储明细还原时将 `mapped_before` 直接设为原始 `before` 的问题。现在前侧依次归一化和映射,后侧归一化,保持与完整结果的显示及 CSV 一致。ZIP 新增 `config_snapshot.json`,便于核对当时配置;详情接口只返回快照模板与版本,不将完整端口映射加入轮询响应。
|
||||
|
||||
页面显示“执行配置已保存”;旧记录显示“旧记录:未保存执行配置”。旧运行无法可靠补造当时的配置,仍保留兼容查询,成功行回查及精简行还原会使用当前配置。快照也不保存原始采集行的副本,若原始批次数据被清理,依赖行 ID 的还原仍会缺少内容。
|
||||
|
||||
### Python 大表内存
|
||||
|
||||
成功样本按“层内序号、层首次出现顺序”排序,只保留样本上限内的候选和分层状态,避免先积累全部成功行。保留原分层轮询顺序;未截断的小表仍保持采集顺序。不需要接口变换时复用输入行;有变换时创建新行,不修改输入数据。稳定身份键顺序直接使用分组字典,省去再次计算全表键、额外键列表与集合。
|
||||
|
||||
每侧 1,000,000 行、50 个邻居分层、全部成功、保存 5,000 条精简样本的测试:优化前引擎新增分配峰值 **1144.43 MiB**,优化后 **420.49 MiB**,下降约 **63.3%**。完整结果与样本顺序的 SHA-256 一致。开启 `tracemalloc` 时耗时为 92.400 秒和 63.681 秒;该计时含内存追踪开销,不代表生产耗时。输入行在追踪开始前创建,峰值不包含输入行、数据库加载或 Python 进程的总内存。
|
||||
|
||||
基线为 `afa8e06b2de64100f963ae30b3babfcb5d7009f4` 中的对比引擎。原始指标见 [百万行测试结果](assets/biz-compare-memory-benchmark.json)。身份键分组仍需要随原表行数增长的内存;这次不是完全流式对比。
|
||||
|
||||
### 大表导出
|
||||
|
||||
导出改为按 `(seq, id)` 游标分批查询、分批还原精简行、逐行将 UTF-8 CSV 写入 ZIP,避免将全部明细与完整 CSV 同时保存在内存。相同 `seq` 的多条结果按 `id` 连续读取,不漏掉跨批次的同行序号记录。保留 BOM、字段顺序及逗号/引号/换行转义。最终压缩包仍由现有接口在内存中返回,压缩文件本身的大小仍计入内存。
|
||||
|
||||
## UI 改动
|
||||
|
||||
结果区分为当前检查项/全表通过率、结果类型、搜索与辅助操作三层。增加明确的分页范围、清空筛选、加载状态、错误重试和搜索无结果提示。筛选按钮增加按下状态,字段筛选增加展开状态与键盘焦点提示。后续增加了执行配置保存状态及旧记录限制提示。
|
||||
|
||||
窄屏检查项导航改为紧凑的横向排列,避免一个检查项占据整行的大块区域。浏览器检查覆盖 1440px、768px、390px;筛选栏没有横向溢出。结果表保留必要的横向滚动。
|
||||
|
||||
- [桌面结果区](assets/biz-compare-desktop.png)
|
||||
- [768px 结果区](assets/biz-compare-narrow.png)
|
||||
- [加载失败与重试](assets/biz-compare-error.png)
|
||||
- [旧记录执行配置提示](assets/biz-compare-legacy.png)
|
||||
|
||||
## 验证
|
||||
|
||||
- Python:87 项通过,1 项百万行基准默认跳过;单独启用百万行基准后通过。新增测试覆盖搜索、历史配置快照、有界抽样与游标导出。
|
||||
- 缓存:6 项 Node 测试通过。
|
||||
- 浏览器:10 个场景通过,包括配置保存状态、旧记录提示、结果布局、错误清除旧明细、重试、清空筛选、窄屏布局、旧任务响应保护、单套轮询、无运行时异常。
|
||||
- Vite 生产打包成功。
|
||||
- 本次业务对比页面的类型错误已经修复。全项目 `tsc -b` 仍被 `BizStatePage.tsx`、`BizMigrationPage.tsx` 中原有的类型/未使用变量错误阻塞。
|
||||
- 页面 ESLint 原有 34 个错误,主要是 `any` 与现有 React Hook 写法;本次未增加错误。结果请求依赖警告已修正。缓存模块没有 lint 错误。
|
||||
- PostgreSQL 路径验证了 SQL 编译与规则降级分支,没有在真实 PostgreSQL 数据库上执行查询或测量执行计划。
|
||||
|
||||
可重复执行的检查:
|
||||
|
||||
```powershell
|
||||
# 项目根目录
|
||||
.venv\Scripts\python.exe -m pytest tests/test_biz_state_compare_export.py tests/test_biz_state_compare_snapshot.py tests/test_biz_state_compare_memory.py tests/test_biz_state_compare_search.py tests/test_biz_state_compare.py tests/test_biz_state_compare_sql.py tests/test_biz_state_compare_recovery.py -q
|
||||
|
||||
# 可选:百万行基准,耗时约数分钟,内存占用较大
|
||||
$env:NETX_BENCH_ROWS = '1000000'
|
||||
$env:NETX_BENCH_REF = 'afa8e06b2de64100f963ae30b3babfcb5d7009f4'
|
||||
.venv\Scripts\python.exe -m pytest tests/test_biz_state_compare_memory.py::test_memory_benchmark_against_git_baseline -q -s
|
||||
Remove-Item Env:NETX_BENCH_ROWS, Env:NETX_BENCH_REF
|
||||
|
||||
# web 目录
|
||||
node --experimental-strip-types --test tests/cutoverDataCache.test.mjs
|
||||
node node_modules/vite/bin/vite.js build
|
||||
node node_modules/typescript/bin/tsc -b
|
||||
```
|
||||
|
||||
浏览器脚本为 `web/tests/bizCompare.browser.mjs`。先启动本地 Vite 服务,再设置 `NETX_PLAYWRIGHT_MODULE` 为可用的 Playwright 包路径;`NETX_TEST_URL` 默认是 `http://127.0.0.1:5179`,浏览器默认使用已安装的 Chrome。所有 `/v1` 请求由脚本提供固定响应,不会访问实际设备或数据库。
|
||||
|
||||
## 后续值得优化的部分
|
||||
|
||||
1. **Python 大表分组。** 有界抽样和冗余复制优化已完成,百万行基准下降约 63% 的引擎新增分配峰值。分组与输入仍随原表规模增长;进一步降低内存可研究排序流式配对或分区执行,并保持重复键配对语义。
|
||||
2. **PostgreSQL 搜索与深分页。** JSON 字段包含搜索和精确总数统计仍可能扫描大量结果。需要用真实数据查看 `EXPLAIN (ANALYZE, BUFFERS)`,再决定常用字段索引、搜索文本索引或游标分页;本次没有盲目添加生产索引。
|
||||
3. **历史配置与原始数据保留。** 新运行的执行配置快照已完成。旧运行仍无法还原未记录的当时配置;精简结果还原依赖原批次行,后续可为批次清理增加引用保护或保留策略。
|
||||
4. **重复键的业务语义。** 引擎按采集顺序配对同键行。如果业务应按集合判断,CLI 行顺序改变可能产生多条“不一致”。当前保留原有语义;可优先完善身份键,或另行实现并测试 Python/SQL 一致的集合匹配。
|
||||
5. **原表回查的数量上限。** 每侧候选命中最多 2000 条,完整分组补齐每侧预算 10000 条,最终展示最多 200 对;这不是全表匹配总数。界面会提示截断,大范围检索需要收窄条件。
|
||||
Loading…
Add table
Add a link
Reference in a new issue