知海

SSR fork 死锁示例说明

vite-main开发与贡献

SSR fork 死锁示例说明

本测试旨在检查一种特定类型的循环依赖,这种依赖会导致棘手的死锁——带有分叉导入栈的死锁

标记说明

text 复制代码
A -> B 表示:B 被 A 导入,且 B 的导入栈中包含 A
A ... B 表示:A 正在等待 B 完成 ssrLoadModule()

H -> X ... Y
H -> X -> Y ... B
H -> A ... B
H -> A -> B ... X

分叉死锁描述

text 复制代码
[X] 正在等待 [Y] 解析
 ↑                  ↳ 正在等待 [A] 解析
 │                                    ↳ 正在等待 [B] 解析
 │                                                      ↳ 正在等待 [X] 解析
 └────────────────────────────────────────────────────────────────────────┘

这看起来像是一个传统的死锁,但使其特殊的是每个模块的导入栈:

text 复制代码
[X] 的栈:
    [H]
text 复制代码
[Y] 的栈:
    [X]
    [H]
text 复制代码
[A] 的栈:
    [H]
text 复制代码
[B] 的栈:
    [A]
    [H]

即使 [X][B] 导入,[B] 也不在 [X] 的栈中,因为 [X] 最初是被 [H] 导入的,所以它的栈只包含 [H][H] 分叉了导入,这使得该问题很难被发现。

修复描述

Vite 在导入 [X] 时,应检查 [X] 是否已经处于 pending 状态;如果是,则必须检查首次导入 [X] 时,[X] 的栈中是否与当前模块存在公共模块。在本例中,[B][X] 共同拥有模块 [H],因此可以推断死锁将会发生。

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。