mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 17:27:31 +00:00
revert: 撤掉多余的 auto_start 门(调度器早已处理)
## 为什么要撤
c426921 我以为"外部插件的 auto_start 完全不生效"。**判断错了。**
实机验证:13 个声明 auto_start=false 的插件在重启后确实没加载
(建链 22 → 11)。靠的是**既有机制**,不是我加的门:
internal/kernelboot/scheduler.go:277 canLaunch: if !p.AutoStart { return false }
internal/kernelmod/pluginhost/mod.go buildSkipSet: catalog 里的插件全交给调度器
internal/kernelmod/pluginhost/catalog_test.go:198 判据已覆盖
我当时只看到 `Load` 遍历目录时不查 auto_start,就断定该字段不生效 ——
那只是**没看到另一条路径**(LoadSkipping + 调度器分层)。
## 为什么必须撤而不是留作"兜底"
· 两处逻辑重叠:调度器按 catalog 决定跳过,我的门在 loadOne 里再判一次。
两处各说各话,将来改一处漏另一处就是新的静默不一致。
· 我那条判据测的是**我自己加的门**,不是真实行为 —— 它变绿不证明任何
产品行为正确(撤掉这道门,判据红,但产品行为不变)。
· **没验证过的防御就是噪音。**
## 撤回后行为不变
按需加载链路实测(weather):
plugin_start → loaded=true / alive=true / pid=838963
plugin_stop → loaded=false / alive=false,pid 消失
两者都 persistent="未改动"(不动持久禁用清单)
这些都发生在**没有**我这个门的旧二进制上。
This commit is contained in:
@ -574,21 +574,6 @@ func pluginEntryHash(plgDir string) string {
|
||||
}
|
||||
|
||||
func (r *Registry) loadOne(plgDir, name string) bool {
|
||||
return r.loadOneOpt(plgDir, name, false)
|
||||
}
|
||||
|
||||
// loadOneOpt 是 loadOne 的显式版本。
|
||||
//
|
||||
// explicitStart=true 表示这是**agent 显式拉起**(plugin_start),
|
||||
// 此时**忽略 auto_start**:插件声明"不自动启动"是"别在开机时拉起我",
|
||||
// 不是"永远不许启动"。
|
||||
//
|
||||
// ★ 2026-10-18 补:在此之前**外部插件的 auto_start 完全不生效** ——
|
||||
// Load 的目录扫描无条件调 loadOne,没有任何地方读 plugin.json 的
|
||||
// auto_start。也就是说这个字段在 plg.json → plugin.json 一路写得出来,
|
||||
// 内核却从不看它:声明 auto_start=false 的插件照样开机自启。
|
||||
// (内置模块那条走的是 kernelboot/scheduler.go,与外部插件是两条路。)
|
||||
func (r *Registry) loadOneOpt(plgDir, name string, explicitStart bool) bool {
|
||||
if r.isDisabled(name) {
|
||||
log.Printf("[plugin] %s is disabled, skipping", name)
|
||||
r.mu.Lock()
|
||||
@ -608,25 +593,6 @@ func (r *Registry) loadOneOpt(plgDir, name string, explicitStart bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ③ auto_start 门(2026-10-18 补:此前外部插件从不检查这个字段)。
|
||||
//
|
||||
// plugin.json 的 auto_start=false 表示"**启用**但不随内核自启",
|
||||
// 用于按需加载的插件(纯工具型,没人调用时不该占进程与工具槽位)。
|
||||
//
|
||||
// 三种启动形态在这里交汇:
|
||||
//
|
||||
// 自动启动 auto_start 缺省/true + 启动扫描 ⇒ 拉起
|
||||
// 启用但不自启 auto_start=false + 启动扫描 ⇒ **跳过**(本门)
|
||||
// 同上 + plugin_start ⇒ 拉起(explicitStart)
|
||||
// 禁用 持久禁用清单 ⇒ 上面的 isDisabled 门挡住,连 plugin_start 也拒
|
||||
//
|
||||
// ★ explicitStart 是关键:声明 false 是"别在开机时拉起我",
|
||||
// 不是"永远不许启动"。没有这个区分,按需插件就再也起不来了。
|
||||
if !explicitStart && !r.shouldAutoStart(plgDir, name) {
|
||||
log.Printf("[plugin] %s 声明 auto_start=false(按需加载),跳过启动扫描;用 plugin_start 可拉起", name)
|
||||
return false
|
||||
}
|
||||
|
||||
// 1) 查找工厂(init 自注册或 RegisterNative)
|
||||
r.mu.RLock()
|
||||
factory, hasFactory := r.factories[name]
|
||||
@ -1098,7 +1064,7 @@ func (r *Registry) ReloadOne(name string) error {
|
||||
r.detachPlugin(name)
|
||||
r.closeDynamic(removed)
|
||||
|
||||
ok := r.loadOneOpt(plgDir, name, true)
|
||||
ok := r.loadOne(plgDir, name)
|
||||
if !ok {
|
||||
return fmt.Errorf("reload plugin %s failed", name)
|
||||
}
|
||||
@ -1312,18 +1278,6 @@ func (r *Registry) DisablePlugin(name, by string) error {
|
||||
|
||||
func (r *Registry) EnablePlugin(name string) error { return r.Enable(name) }
|
||||
|
||||
// shouldAutoStart 读 plugin.json 的 auto_start(缺省 = true)。
|
||||
//
|
||||
// 读不到 manifest 时返回 true:宁可多启动一个(与旧行为一致),
|
||||
// 也不要因为清单文件损坏而让插件静默不启动 —— 后者更难查。
|
||||
func (r *Registry) shouldAutoStart(plgDir, name string) bool {
|
||||
mft := readManifest(plgDir)
|
||||
if mft == nil {
|
||||
return true
|
||||
}
|
||||
return mft.ShouldAutoStart()
|
||||
}
|
||||
|
||||
// isRuntimeStopped 报告插件是否处于**运行态关闭**(设计 §2.6.7.3)。
|
||||
func (r *Registry) isRuntimeStopped(name string) bool {
|
||||
r.mu.RLock()
|
||||
|
||||
Reference in New Issue
Block a user