Replies: 1 comment
|
插件 fiber 销毁时 watcher 未 deactivate/drain——生命周期管理的典型坑(注册与清理不对称)。 插件开发时注意:ctx.dispose 里显式清理 watcher/异步任务。生命周期规范见第 4 章:https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/04-plugin-dev.md |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
Disposing the plugin fiber that owns a settings namespace removes the registration immediately, but it does not deactivate or drain that registration's asynchronous watchers. A callback can therefore continue running—or a queued callback can start—after its owner has finished tearing down resources.
I reproduced the lifecycle race with a regression test and prepared a tested fix in a public fork. Since the repository disables external pull requests, I am sharing the patch here according to
CONTRIBUTING.md.Reproduction
Before the fix, the fiber disposal resolves while the first callback is still running. Once released, the second callback also starts even though the registration owner has already been disposed.
Root cause
The registration effect disposer only deleted the namespace from the service registry:
The watcher disposer and service-level teardown already use an
activeflag and serialized watcher tails, but registration teardown did not apply those mechanisms. Removing the namespace prevented future commits from discovering the registration; it did not stop callback work that had already been chained.Impact
Settings owners commonly use watchers to reconfigure routes, adapters, or other resources. A callback that runs after the owner fiber has disposed can touch released resources, recreate state during unload, or apply stale configuration after a replacement plugin has registered the same namespace. Registration disposal also reports completion before the owner's asynchronous observer work is quiescent.
Proposed fix
Registration teardown now:
Queued invocations observe the inactive flag and skip; invocations that already started finish before owner disposal resolves.
3039ff829cmaster: deepseek-ai:master...Lzb-gzist:agent/settings-registration-disposal-quiescenceagent/settings-registration-disposal-quiescenceValidation
masterbecause owner disposal resolves before the held watcher completes.pnpm exec vitest run packages/settings/settings/tests packages/settings/settings-file/tests— 154 tests passed after the fix.pnpm exec tsc -b packages/settings/settings/tsconfig.json --pretty false— passed.pnpm run lint— passed.pnpm run doc-sync— 28/28 gates passed.All reactions