refactor: 取 VM 的三条路径合一,newVM 成为唯一入口
borrow(池化)、ensure(实例)、borrowStatic(静态)各自写了一遍「取作用域 →
拼 extra → 建 Runtime → load」。borrowStatic 甚至把 newVM 逐行抄了一遍,只为把
noInstance 传成 true。
结果就是规则会漏:上一个 commit 修的「borrowStatic 没标 scoped」正是这么来的。
现在三条都走 newVM,作用域注入和 scoped 标记只有一份。
顺带删掉两处无意义的间接:
loadInto s.load(ctx, rt, ctorArgs, false) 的单行包装,只被 newVM 调一次
newRuntime 它的 scope 参数两个调用点都传 s.name,而注释描述的「会话 VM 用
会话 key」这条路径根本没实现(作用域 key 走的是 vmGlobals)。
参数名还跟同包的 type scope struct 撞名
**scope 是显式参数,不是从 ctx 嗅的**——这一点差点被我改坏:Instance 重建 VM
时要回到它**创建时**那个作用域,而不是当次调用 ctx 里的。对一个作用域实例调
Call(context.Background()) 不该把它的扩展弄丢。加了
TestScope_实例重建VM后仍在原作用域 守这条,用超时逼出 VM 重建(第一版用抛异常,
那不会丢 VM,两种写法都通过,等于没测)。
This commit is contained in:
@@ -79,23 +79,7 @@ func (s *Script) borrowStatic(ctx context.Context) (*vmHandle, error) {
|
||||
return nil, newError(KindClosed, s.name, "", ErrClosed, "脚本已关闭")
|
||||
}
|
||||
|
||||
var extra map[string]any
|
||||
if sc, ok := scopeOf(ctx); ok {
|
||||
extra = sc.vmGlobals()
|
||||
}
|
||||
|
||||
rt, err := s.engine.newRuntime(s.name, extra)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm, err := s.load(ctx, rt, nil, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 带作用域的 VM 装着那个作用域的扩展,绝不能回池。今天 staticTarget.finish
|
||||
// 永远丢弃,标不标都不漏;但同一个约束不该靠两套机制守——以后有人把静态 VM
|
||||
// 接进 release,漏标就是一次跨请求泄漏
|
||||
vm.scoped = extra != nil
|
||||
return vm, nil
|
||||
sc, _ := scopeOf(ctx)
|
||||
// noInstance:静态方法挂在 class 上,不用白跑一遍 constructor
|
||||
return s.newVM(ctx, sc, nil, true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user