mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-15 12:15:16 +00:00
refactor(proc)!: 版本身份只由版本号本身承载,删除全部自定版本号
内核侧配合 SDK 仓 b2872f3:兼容性不再依赖任何自造版本号。
删除三处自造号:
- ProtocolVersion(协议号)→ 改为比对主版本段(MajorVersion)
- shmVersion(共享段 header)→ 改为校验描述符个数(field_count)
- unifiedVersion(SuperBlock)→ 结构自描述,不再校验
握手契约随之调整:
HandshakeParams: protocol(int) → core_version(string)
HandshakeResult: protocol(int) → sdk_version 承担判据
内核比对 MajorVersion(meta.Version) == MajorVersion(res.SDKVersion),
跨主版本即拒并提示重编(主版本跃迁 = 破坏性变更的定义)。
为什么废除:额外的号需要人去记得升,而它没有任何结构性约束兜底,
必然腐烂。实证:ProtocolVersion 常量在多次布局变更里只升过一次,
对应的守卫测试长期失败无人察觉(期望 18/1,实际 19/2)。
新增判据:
- TestProcess_MajorVersionMismatchRejected:跨主版本被拒(testdata/badproto)
- TestProcess_SameMajorDifferentMinorAccepted:同主版本放行(新增 testdata/oldminor)
后者是 §七「1.x 内纯追加、不调新面不用重编」规约的落地 —— 若误用全等
比较,未重编的存量插件会被无谓地全部拒绝。
两条均经变异验证:改成全等比较 → 前者过/后者挂;删掉校验 → 前者挂。
This commit is contained in:
@ -187,7 +187,7 @@ func main() {
|
||||
shm = m[ctxOff : ctxOff+ctxSize]
|
||||
}
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2, "sdk_version": "test",
|
||||
"sdk_version": "1.0.0",
|
||||
"plugin_name": "append-" + tag, "pid": os.Getpid(),
|
||||
}})
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
//go:build ignore
|
||||
|
||||
// badprotoplugin 上报错误的协议版本,验证内核显式拒绝而非半兼容运行。
|
||||
// badprotoplugin 上报不同主版本的 SDK,验证内核显式拒绝而非半兼容运行。
|
||||
//
|
||||
// 主版本跃迁是破坏性变更的定义(如 1.0.0 从 C ABI 改子进程),
|
||||
// 所以它是兼容性的正确分界——不需要另一个自定的协议号来复述。
|
||||
package main
|
||||
|
||||
import (
|
||||
@ -38,8 +41,7 @@ func main() {
|
||||
}
|
||||
if req.Method == "handshake" {
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 999, // 故意不匹配
|
||||
"sdk_version": "ancient",
|
||||
"sdk_version": "99.0.0", // 主版本不同,故意不匹配
|
||||
"plugin_name": "badproto",
|
||||
"pid": os.Getpid(),
|
||||
}})
|
||||
|
||||
@ -95,8 +95,7 @@ func main() {
|
||||
switch req.Method {
|
||||
case "handshake":
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2,
|
||||
"sdk_version": "test",
|
||||
"sdk_version": "1.0.0",
|
||||
"plugin_name": "cb",
|
||||
"pid": os.Getpid(),
|
||||
}})
|
||||
|
||||
2
internal/plugin/proc/testdata/crashplugin.go
vendored
2
internal/plugin/proc/testdata/crashplugin.go
vendored
@ -40,7 +40,7 @@ func main() {
|
||||
switch req.Method {
|
||||
case "handshake":
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2, "sdk_version": "test", "plugin_name": "crash", "pid": os.Getpid(),
|
||||
"sdk_version": "1.0.0", "plugin_name": "crash", "pid": os.Getpid(),
|
||||
}})
|
||||
case "tool.invoke":
|
||||
// 模拟插件 bug:直接 panic,进程带非零码退出
|
||||
|
||||
3
internal/plugin/proc/testdata/echoplugin.go
vendored
3
internal/plugin/proc/testdata/echoplugin.go
vendored
@ -43,8 +43,7 @@ func main() {
|
||||
switch req.Method {
|
||||
case "handshake":
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2,
|
||||
"sdk_version": "test",
|
||||
"sdk_version": "1.0.0",
|
||||
"plugin_name": "echo",
|
||||
"pid": os.Getpid(),
|
||||
}})
|
||||
|
||||
2
internal/plugin/proc/testdata/forkplugin.go
vendored
2
internal/plugin/proc/testdata/forkplugin.go
vendored
@ -57,7 +57,7 @@ func main() {
|
||||
switch req.Method {
|
||||
case "handshake":
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2, "sdk_version": "test", "plugin_name": "fork", "pid": os.Getpid(),
|
||||
"sdk_version": "1.0.0", "plugin_name": "fork", "pid": os.Getpid(),
|
||||
}})
|
||||
case "tool.invoke":
|
||||
// 不回应答,直接退出:模拟插件突然死亡(崩溃/被 kill)。
|
||||
|
||||
2
internal/plugin/proc/testdata/hangplugin.go
vendored
2
internal/plugin/proc/testdata/hangplugin.go
vendored
@ -42,7 +42,7 @@ func main() {
|
||||
switch req.Method {
|
||||
case "handshake":
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2, "sdk_version": "test", "plugin_name": "hang", "pid": os.Getpid(),
|
||||
"sdk_version": "1.0.0", "plugin_name": "hang", "pid": os.Getpid(),
|
||||
}})
|
||||
case "tool.invoke":
|
||||
// 永久卡住,永不回应答
|
||||
|
||||
57
internal/plugin/proc/testdata/oldminorplugin.go
vendored
Normal file
57
internal/plugin/proc/testdata/oldminorplugin.go
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
//go:build ignore
|
||||
|
||||
// oldminorplugin 上报同主版本但更早的中版本 SDK,验证内核**不会**无谓拒绝。
|
||||
//
|
||||
// 规约(docs/git-branching.md §七.1):1.x 内的中版本跃迁全部是纯追加 ——
|
||||
// 新增方法由插件调用、内核实现,不调就不受影响。因此未重编的存量插件
|
||||
// (如用 SDK 1.0.0/1.1.0 编的)必须能在新内核上直接建链。
|
||||
//
|
||||
// 若判据误用「全等比较」而非「主版本比较」,这条会失败 —— 正是它的价值。
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
type request struct {
|
||||
ID uint64 `json:"id,omitempty"`
|
||||
Method string `json:"method"`
|
||||
Params json.RawMessage `json:"params,omitempty"`
|
||||
}
|
||||
|
||||
type response struct {
|
||||
ID uint64 `json:"id"`
|
||||
Result interface{} `json:"result,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
in := bufio.NewScanner(bufio.NewReader(os.Stdin))
|
||||
out := bufio.NewWriter(os.Stdout)
|
||||
send := func(v interface{}) {
|
||||
b, _ := json.Marshal(v)
|
||||
out.Write(b)
|
||||
out.WriteByte('\n')
|
||||
out.Flush()
|
||||
}
|
||||
|
||||
for in.Scan() {
|
||||
var req request
|
||||
if err := json.Unmarshal(in.Bytes(), &req); err != nil {
|
||||
continue
|
||||
}
|
||||
if req.Method == "handshake" {
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"sdk_version": "1.0.0", // 同主版本,更早的中版本
|
||||
"plugin_name": "oldminor",
|
||||
"pid": os.Getpid(),
|
||||
}})
|
||||
continue
|
||||
}
|
||||
if req.ID != 0 {
|
||||
send(response{ID: req.ID})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,7 +139,7 @@ func main() {
|
||||
shm = m[ctxOff : ctxOff+ctxSize]
|
||||
}
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2, "sdk_version": "test", "plugin_name": "readonly", "pid": os.Getpid(),
|
||||
"sdk_version": "1.0.0", "plugin_name": "readonly", "pid": os.Getpid(),
|
||||
}})
|
||||
|
||||
case "plugin.init":
|
||||
|
||||
2
internal/plugin/proc/testdata/stageplugin.go
vendored
2
internal/plugin/proc/testdata/stageplugin.go
vendored
@ -354,7 +354,7 @@ func main() {
|
||||
shm = m[ctxOff : ctxOff+ctxSize]
|
||||
}
|
||||
send(response{ID: req.ID, Result: map[string]interface{}{
|
||||
"protocol": 2, "sdk_version": "test", "plugin_name": "stage", "pid": os.Getpid(),
|
||||
"sdk_version": "1.0.0", "plugin_name": "stage", "pid": os.Getpid(),
|
||||
}})
|
||||
|
||||
case "plugin.init":
|
||||
|
||||
Reference in New Issue
Block a user