koishijs / koishi

Cross-platform chatbot framework made with love
https://koishi.chat
MIT License
4.37k stars 237 forks source link

Bug: `hmr` 在包含循环引用的代码中触发多次reload并导致插件duplicate #1110

Closed Hieuzest closed 1 year ago

Hieuzest commented 1 year ago

Describe the bug

hmr 在包含循环引用的代码中触发多次reload并导致插件duplicate

Steps to reproduce

测试插件包含两个文件:

index.ts

import { Context } from 'koishi'
import { Foo } from './foo'
export class Test{
  constructor(ctx: Context) {
    ctx.plugin(Foo)
  }
}
export default Test

foo.ts

import { Context } from 'koishi'
import Test from '.'
export class Foo {
  constructor(ctx: Context) {
    Test
  }
}
export default Foo

启动koishi后,保存以上任意文件,hmr会触发两次reload,并报duplicate plugin

如果foo.ts不使用默认导出,则不会reload两次

Expected behavior

不会导致duplicate plugin

Screenshots

{A486AEF1-CCBB-4331-A0EF-4D520B7C0916} (此处保存了三下)

Versions

Additional context

No response

shigma commented 1 year ago
image

我咋没有复现呢,你用最新版本试试?

Hieuzest commented 1 year ago

我也复现不出来,原问题应该已经不存在了 不过当时遇到此问题时的场景和我现在所处的场景是一致的,问题也是一直存在的 我现在遇到的问题更像是 #1130 ,是由using触发的,具体复现:

index.ts

import { Context, Service } from 'koishi'
import { Foo } from './foo'

export class Test extends Service {
  constructor(ctx: Context) {
    super(ctx, 'test')
    ctx.plugin(Foo)
  }
}

export default Test

foo.ts

import { Context } from 'koishi'

export class Foo {
  static using = ['test']

  constructor(ctx: Context) {
    console.log('foo!')
  }
}
shigma commented 1 year ago

1130 已经修了吧,你这个说的是 hmr 问题还是 1130 本身?

Hieuzest commented 1 year ago

cordis已经确认为最新 上述含有using的代码在hmr reload时仍然存在问题

shigma commented 1 year ago

感谢复现,已修复,请等待下一个版本。

Hieuzest commented 1 year ago

后续。仍然是上述包含using的代码并无修改,在每一次dispose时,内侧的Foo并不能被正常collect,导致此对象与一组listener没有回收,重复多次即报maxListeners。hmr或手动在控制台开关均可触发。 推测为新增的isActive在EffectScope::reset中错误地提前返回所致。

shigma commented 1 year ago

后续。仍然是上述包含using的代码并无修改,在每一次dispose时,内侧的Foo并不能被正常collect,导致此对象与一组listener没有回收,重复多次即报maxListeners。hmr或手动在控制台开关均可触发。 推测为新增的isActive在EffectScope::reset中错误地提前返回所致。

此 issue 对应的问题已修复但还没更新。如果汇报的是其他问题最好重新提供复现。

Hieuzest commented 1 year ago

1.我本地一直使用的是最新的cordis commit 2.复现正是三楼原本的代码无需改动 只需在register internal/service处打印hooks.length,即可观测到每一次reload时listeners都会+1,更进一步地得到上面我所提及的结论 image

shigma commented 1 year ago

感谢复现,已修复。