Skip to content

fix(bukkit): 收紧 Folia 调度与背包线程所有权#712

Open
zhibeigg wants to merge 1 commit into
TabooLib:dev/6.3.0from
zhibeigg:fix/703-bukkit-folia-threading
Open

fix(bukkit): 收紧 Folia 调度与背包线程所有权#712
zhibeigg wants to merge 1 commit into
TabooLib:dev/6.3.0from
zhibeigg:fix/703-bukkit-folia-threading

Conversation

@zhibeigg

@zhibeigg zhibeigg commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

原有问题

Bukkit/Folia 调度与背包操作没有始终遵守对象所属线程:

  • Folia 的全局、区域、实体和异步调度被混用,部分路径通过阻塞等待跨区域结果。
  • 菜单、分页、虚拟背包及相关 NMS 操作可能从异步线程或错误区域直接访问 Player、Inventory、World。
  • 物品扣除边遍历边修改背包;当总数量不足时,前面槽位已经被扣除,无法原子回滚。

典型触发场景与后果

  • Folia 服务器上从异步数据库回调打开或刷新玩家菜单:触发线程检查异常,或与玩家点击同时修改背包造成竞态。
  • 玩家移动区域、插件禁用或任务取消时仍执行旧区域任务:访问失效实体、重复提交 UI 更新或遗留任务。
  • 扣除数量跨多个槽位,最终发现物品不足:玩家仍损失部分物品,takeList 与实际背包状态不一致。
  • 在区域线程中阻塞等待其他区域:可能卡住区域 tick,放大为服务器卡顿。

本 PR 修改

  • 明确区分 Folia 全局、区域、实体和异步调度,移除跨区域阻塞等待,并提供 CompletableFuture 形式的非阻塞结果入口。
  • 将菜单创建、分页刷新、虚拟背包提交和相关 NMS 操作封送到玩家所属线程。
  • 补齐任务取消、插件禁用和调度失败的终态传播。
  • 将物品扣除改为“先计算完整扣除计划,再一次性应用”;数量不足时不修改 Inventory 或 takeList
  • 增加 fake scheduler、UI 线程所有权和物品跨槽/不足边界测试。

修改目的

遵守 Bukkit 与 Folia 的线程模型,避免跨线程访问、区域线程阻塞和背包部分修改,保证 UI 与物品操作具备确定且原子的结果。

兼容性与行为变化

  • 保持现有同步 API,并增加可用于异步链路的 Future 入口。
  • 原本在错误线程立即执行的操作会改为在正确的玩家/区域线程调度。
  • 物品不足时由“可能部分扣除”改为“完全不修改”。

验证

  • 相关 Bukkit/Folia/UI/NMS 模块无缓存串行测试
  • git diff --check
  • 独立只读复审

Refs #703

避免无上下文同步任务错误落到全局区域线程,并让 UI、虚拟背包与 NMS 操作按玩家或区域线程执行;同时保证物品数量不足时不发生部分扣除。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant