Conversation
- 将 CDR #2309 的实例同步修复迁入 CDC,仅为 get/forget 添加同步标志。 - 保留上游方法体,增加模组门控、结构校验及补丁应用日志。 - 添加真实 KubeJS JAR 回归任务与后续游戏测试、HotAI 迁移文档。 验证:Java 17 完整构建通过;build.24 两轮各 200 万次并发回归中, 原版空值 83,275/63,875 次,转换后均为 0;缓存、过期及异常重试通过。 完整 Forge 加载、冷启动进档和独立服务器测试留待草稿 PR 后续验证。
- 审计 KubeJS 资源生成、脚本 API 和外部直接引用,区分内部竞态与 ProbeJS 调用。 - 用受控锁顺序夹具确认整方法同步能新增死锁,改用原子快照并在无缓存锁时执行 factory。 - forget 发布独立身份,阻止失效前的计算回填;保留合法 null、绝对过期和异常传播。 - 更新回归工具、兼容台账、并发语义和后续游戏测试说明。 验证:Java 17 完整构建和 reobf 通过;KubeJS build.16/24/26 各 200 万轮 并发回归补丁版均为零空值,缓存/过期/异常/失效中计算和锁顺序探针通过。 完整 Forge 冷启动、连续 reload 和独立服务器尚未执行,PR 继续保持草稿。
This was referenced Sep 18, 2026
[fix] 消除之前KJS Lazy竞态修复潜在的死锁问题; [conf] 最大帧率设为无限制,解绑所有闪避键避免误触
Jasons-impart/Create-Delight-Remake#2324
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题与最终实现
KubeJS 自身的资源读取通过
GeneratedData.get()调用Lazy.get(),并可能随后forget();并发读写分离的 cached/value 字段时,正常 supplier 也可能返回空缓存。这条路径不依赖 ProbeJS。关联 CDR #1736 与 CDR #2309。本 PR 通过 CDC Mixin 插件为每个 Lazy 添加独立的原子缓存状态,修复该竞态,同时避免持有 Lazy 锁执行任意 factory 回调:
LazyMixin使用字符串目标、@Pseudo、关闭 remap,并按 KubeJS 是否存在门控。KubeJsLazyCache,将两个方法桥接到 helper;不引入 KubeJS 编译依赖。AtomicReference<Snapshot>一次读取/发布 cached 与 value,合法 null 也能缓存;factory 执行期间不持缓存锁、不等待其他计算。forget()发布新的空快照,使失效前开始的计算无法回填或覆盖失效后的新值。本实现替换 get/forget 方法体并初始化新字段,已不属于只修改访问标志的等价补丁;升级 KubeJS 或与其他同目标补丁共存时必须复核。父整合包 HotAI、Packwiz、子模块指针、运行 JAR 和 CDC 版本号均未修改。
死锁审计依据
ResourceGenerator.add接受任意Supplier<byte[]>,Utils.lazy/expiringLazy暴露任意脚本 supplier,并有后台线程 API;BlockEntityAttachmentType.ALL的 factory 还会执行插件注册回调。因此不能为所有 factory 保证统一的外部锁顺序。externalLock -> Lazy.get()与Lazy.get() -> factory -> externalLock的受控夹具:原版和原子缓存版均完成,整方法 synchronized 版被 JVMThreadMXBean确认存在两个线程的监视器死锁。已完成验证
Java 17.0.12 / Gradle 8.8 完整构建、reobf 与
git diff --check通过。测试直接调用生产插件改写真实发行 JAR 中的 Lazy.class,并加载 CDC helper 执行:build.16 测试 JAR 的 SHA-256 为
3de6b7267d3aab981848ed54d3afe7edf20532fa4060631fd6fffcd99ac5f3d5,与 #2309 的输入一致。原版空值次数随线程调度变化。同时通过:改写范围校验、幂等、结构不符时不部分修改、缓存命中、合法 null、过期、supplier 异常后跨线程重试、计算中连续 forget(含新值已填充/未填充两种情况)、并发 miss,以及 factory 等待另一线程执行 forget。
独立测试没有启动完整 Forge/Mixin 加载管线,不代表模组门控、辅助类加载时序、冷启动进档或游戏
/reload已经验证。原子缓存自身不建立回调锁依赖,但也不保证任意脚本/模组本身不会死锁,不承诺零性能损失。待测与迁移
hotai/dev/latvian/mods/kubejs/util/Lazy.badiff后完整重启;不要叠加旧二进制差分。[CDCore][KubeJSLazy] Applied atomic cache日志;导出 class 含 cache 字段/构造器初始化/helper 调用,get/forget 无ACC_SYNCHRONIZED。GUN_DATA=null、Couldn't place player;验证 TACZ 同步、JEI 注液配方/流体标签。本轮客户端未运行,当前会话没有 Minecraft MCP 工具,完整游戏压力测试仍待环境接入。PR 保持草稿;通过上述回归后再单独提交父整合包 CDC 升级和旧 HotAI 移除。审计、复测命令和回滚说明见
docs/dev-knowledge/kubejs-lazy.md。