From 5af2a868167329efb2c28b6c188cc456c5624fca Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 21 Sep 2026 10:34:27 +0800 Subject: [PATCH] =?UTF-8?q?docs(sdk):=20=E8=A1=A5=E5=85=A8=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=87=8D=E5=90=AF=E7=9A=84=E7=9C=9F=E5=AE=9E=E7=BA=A6?= =?UTF-8?q?=E6=9D=9F=EF=BC=88=E9=80=80=E9=81=BF=20/=20=E4=B8=8A=E9=99=90?= =?UTF-8?q?=20/=20=E9=9D=9E=E6=97=A0=E6=84=9F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原文只说「插件崩溃时平台自动拉起,保障服务可用性」,读起来像 无感瞬时恢复。实测与源码都不是这样: ## 补齐的默认参数(内核 internal/plugin/registry.go) | 参数 | 值 | 含义 | |---|---|---| | procRestartBackoff | 1s | 第 n 次重启前等 n × 1s(线性退避) | | procMaxRestarts | 3 | 窗口内重启次数上限 | | procCrashWindow | 5min | 窗口内无新崩溃则计数归零 | 即实际序列 1s → 2s → 3s;同一 5 分钟窗口内第 4 次崩溃(n > 3)不再 自动拉起,交人工介入。首次重启就要等 1s,期间该插件的工具是缺席的、 调用会报错 —— 需要秒级就位的插件应在 OnStart 里自建重连与状态重建。 ## 顺带改准一处混淆 `SetAutoRestart` 的文档写「崩溃后自动重载」—— 把「重启」说成了 「重载」。重载是换 plugin.bin 后重新加载那条路径(ReloadOne), 与崩溃自愈不是一回事。已在文档里写清,并附上退避与上限。 这个混淆与内核侧 HEAD 修正的 README/官网是同一处(源码注释里 「足够快到用户感知不到工具缺席」也是同一类无实测支撑的主观断言, 已在主仓同批改掉)。 中英双版同步更新。 --- README.md | 12 ++++++++++++ README_EN.md | 13 +++++++++++++ sdk/plugin.go | 6 +++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b583aab..24445ab 100644 --- a/README.md +++ b/README.md @@ -487,6 +487,18 @@ enabled := sdk.AutoRestart() 插件崩溃时平台自动拉起,保障服务可用性。 +重启是**有节制的**,默认参数(内核 `internal/plugin/registry.go`): + +| 参数 | 值 | 含义 | +|---|---|---| +| `procRestartBackoff` | `1s` | 第 n 次重启前等 `n × 1s`(线性退避,非立即拉起) | +| `procMaxRestarts` | `3` | 窗口内允许的重启次数上限 | +| `procCrashWindow` | `5min` | 窗口内无新崩溃则计数归零 | + +即崩溃后的实际序列是 **1s → 2s → 3s**;同一 5 分钟窗口内第 **4** 次崩溃 +(`n > 3`)**不再自动拉起**,交人工介入。这不是「立即无感恢复」—— +如果插件需要秒级就位,请自己在 `OnStart` 里做好重连与重建。 + > ⚠️ `SetAutoRestart` 的典型用法是「外部连接建好后再判定能否自动重启」,而连接建立 > 通常在后台 goroutine 里,内核又在另一个 goroutine 读它——这对读写天然并发。 > **SDK 1.1.0 已给这个标志与全部 API 字段加锁**(`-race` 实测 11 处竞态, diff --git a/README_EN.md b/README_EN.md index d717c70..517122d 100644 --- a/README_EN.md +++ b/README_EN.md @@ -443,6 +443,19 @@ enabled := sdk.AutoRestart() The platform automatically restarts the plugin on crash, ensuring service availability. +Restarts are **rate-limited**. Defaults (kernel `internal/plugin/registry.go`): + +| Parameter | Value | Meaning | +|---|---|---| +| `procRestartBackoff` | `1s` | Before restart #n, wait `n × 1s` (linear backoff, not immediate) | +| `procMaxRestarts` | `3` | Max restarts within the window | +| `procCrashWindow` | `5min` | No new crash within the window resets the count | + +So the actual sequence is **1s → 2s → 3s**; the **4th** crash in the same 5-minute +window (`n > 3`) is **not** restarted automatically and needs manual intervention. +This is not instant, invisible recovery — if your plugin must be back in seconds, +reconnect and rebuild your own state in `OnStart`. + > ⚠️ `SetAutoRestart` is typically used to decide whether auto-restart is safe *after* an > external connection has been established, and that connection setup usually happens in a > background goroutine while the kernel reads the flag from another one — which is inherently diff --git a/sdk/plugin.go b/sdk/plugin.go index a1fab03..ce1311d 100644 --- a/sdk/plugin.go +++ b/sdk/plugin.go @@ -775,8 +775,12 @@ func (s *PluginSDK) SetToolBlocks(blocks []ContentBlock) { } } -// SetAutoRestart 设置插件是否允许内核自动重启(崩溃后自动重载)。 +// SetAutoRestart 设置插件崩溃后内核是否自动重启它。 // 默认 true。如果插件有无法恢复的状态(如外部连接),应设为 false。 +// +// 重启是有限度的:线性退避(第 n 次等 n×1s,即 1s→2s→3s), +// 且同一 5 分钟窗口内第 4 次崩溃就停下不再拉起(详见 README)。 +// 注意这与「重载」(换 plugin.bin 后重新加载)是两回事。 func (s *PluginSDK) SetAutoRestart(enabled bool) { s.apiMu.Lock() s.autoRestart = enabled