Files
go-omni/reports/copyxAcceptance.md

83 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# v0.19 copyx 与映射移除验收
日期:2026-09-25。环境:Apple M2 Max、darwin/arm64、Go 1.27.1,基准默认 GOMAXPROCS=12。最低支持版本另用 Go 1.22.12 验证 copyx 与可运行示例。
## 范围与行为
本轮新增可选 Go 工具包并删除原映射配置/生成机制,没有修改接入项目代码、数据库或线上服务。没有新增第三方依赖,没有内置工资、金额或权限规则;工资只是生成器的独立通用验收 fixture。
| 场景 | 验证内容 |
| --- | --- |
| 浅/深复制 | 值、结构、指针、数组、map、slice、interface;浅共享与深隔离分别验证 |
| 空值与精度 | nil 与空集合、默认保留 false/0、显式 nil/skip 策略;不兼容类型不能借 nil/零值绕过检查 |
| 可变引用 | 原指针/map、子切片、零长度但有容量的视图、源元素指针、私有子引用、其他字段的引用均拒绝 |
| 自定义函数 | 字段改名、精确类型对、金额私有状态复制、nil interface;重复/冲突配置拒绝 |
| 失败语义 | errors.Is 保留 cause、目标不提交部分结果、嵌入目标指针不提前修改 |
| 对象图 | 指针/map/slice 循环,重复引用;循环指针根压成值结构拒绝 |
| 并发与资源 | 同一 Copier 64 goroutine 各复制 20 次,race;深度/节点/估算分配超限拒绝;锁/资源/函数等明确限制 |
| 真正生成的消费者 | 三端工资公共字段,Money scalar,大数精度/舍入、非法金额、缺失/null/零值、完整表单、错误码与错误链 |
| 维护成本 | 公共字段新增:改一处契约和一处独立业务结构;三个接口共用 helper,不增加拷贝规则 |
| 生成与生命周期 | 重复 generate/check/dry-run 保留业务文件;工厂异常、初始化/监听失败及资源关闭由既有回归验证 |
| 移除与 workspace | 旧配置/旧生成文件阻断且不写入,明确迁移后所有权清理;workspace 失败不部分更新服务 |
FuzzClone 使用动态 JSON 容器、随机 bytes 和嵌套 slice,验证值一致与引用隔离。输入超过 1 KiB 时截取继续验证,运行 30 秒、4 workers:**4,237,917 次执行,未发现失败**。这不等于所有形状都已 fuzz;循环、类型转换及资源拒绝另外用定向用例覆盖。
全量 46 个测试包通过 race 回归(含实际生成项目),vet/build、Go 1.22.12、示例运行与生成漂移检查均通过。
## 可复现命令
```sh
GO_OMNI_SCAFFOLD_INTEGRATION=1 go test -race -count=1 ./...
go vet ./...
go build ./...
GOTOOLCHAIN=go1.22.12 go test ./copyx ./examples/copying
go test ./copyx -run '^$' -fuzz FuzzClone -fuzztime 30s -parallel 4
go test ./copyx -run '^$' -bench . -benchmem -benchtime 300ms -count 3
go run ./examples/copying
go run ./cmd/go-omni api generate --dir examples/managedService --check
# examples/managedService 中另执行 go test -race ./... 与 go build .
```
全量回归包含真实临时生成项目,集成测试的子进程使用 go test -race / go build,并不只比较生成字符串。基准测量时没有同时运行本轮 fuzz 或全量测试;原始三轮结果见 [copyxBenchmark.txt](copyxBenchmark.txt)。
## 性能与分配
下表取三轮中位数。构造器复用与一次性调用都包含真实复制;`fields1000` 指整数 slice 的长度,不是 1,000 个结构字段。所有深拷贝保留引用检查。
| 场景 | 中位耗时 | B/op | allocs/op |
| --- | ---: | ---: | ---: |
| 相同结构浅拷贝(含引用字段) | 85.8 ns | 96 | 2 |
| 3 字段跨结构改名,复用 Copier | 697.5 ns | 168 | 7 |
| 相同跨结构,每次构建 Copier | 1,181 ns | 1,120 | 17 |
| 嵌套结构 + 1 个整数 + map,深拷贝 | 2,758 ns | 1,368 | 42 |
| 嵌套结构 + 100 个整数 + map,深拷贝 | 2,787 ns | 2,256 | 42 |
| 嵌套结构 + 1,000 个整数 + map,深拷贝 | 3,806 ns | 9,552 | 42 |
| 64 KiB byte slice 深拷贝 | 5,780 ns | 65,768 | 9 |
| 100 项 map,每项含整数 slice | 88,859 ns | 87,704 | 1,554 |
| 自引用循环对象深拷贝 | 2,128 ns | 640 | 26 |
| converter 新建 slice 并通过检查 | 539.7 ns | 280 | 10 |
| converter 返回原 slice 被拒绝 | 383.8 ns | 320 | 11 |
并行循环对象基准中位 515.2 ns/op 是多核聚合吞吐均摊,**不是单请求延迟**。复杂 map 的多次图扫描、字段路径和反射分配明显更贵;不据此宣称运行时工具快于手写赋值。热点复用 Copier;大对象和高频映射应按实际业务结构衡量是否改用直接 Go。
优化只包括不可变类型元数据缓存、纯值快速路径、纯值 slice 批量复制;没有去掉深拷贝别名检查。内置估算分配上限 64 MiB 不是硬堆内存隔离,converter 的外部分配及副作用不受该预算控制。
## 边界
- 新方式在运行时做类型与覆盖检查,不再有旧映射生成时的静态保证;字段变更要运行实际类型对测试。
- converter 是受信项目代码,必须只读输入;不能自动回滚其副作用、证明其未共享外部全局对象,或强杀无限循环。
- 当前记录是本机库/生成器验收,不是线上服务吞吐、Linux soak、真实业务数据库回归或 OSS/R2 云账号验收。本轮没有对线上服务器施压。
- 旧消费者仍需按 [COPY.md](../COPY.md#从旧-mapping-迁移) 迁移,不会被这次框架发布自动修改。
## 发布后远程验收
标签 `v0.19.0-preview` 固定在 `fd83235ce7fc15ce88a482d385d70e61f25d7b32`。空 module 缓存安装远程 CLI,消费者固定同版依赖、具有校验和、无本地 replace,7 组实际生成消费者 race 回归通过;包含三端 copyx 示例。
根目录 `go run .` / 构建、nethttp/native 的 SIGINT/SIGTERM、404/405、Go 错误目录、原始回调、上传/下载、workspace 共用错误目录及资源收尾均通过。远程单独执行 `go run git.yuntuo.hk/k2safe/go-omni/examples/copying@v0.19.0-preview` 也验证深拷贝隔离与共享 converter 拒绝。
```sh
python3 scripts/verifyManagedRelease.py --version v0.19.0-preview --report reports/copyxRemote.json
```
发布后验收工具同步移除了旧 mapping 用例,改为 copyx 消费者并核对实际远程依赖校验和。详细检查项、源摘要见 [copyxRemote.json](copyxRemote.json)。标签不随验收记录的后续文档提交移动。