Platform / 平台
macOS
Lithe version / Lithe 版本
e19928bd (main)
OS and architecture / 操作系统与架构
macOS 15.7.3, Apple Silicon (arm64)
Environment / 环境信息
JDK: 1.8.0_461
Maven: 项目自带 pom.xml(未使用 wrapper)
Rust: 1.94.0
目标项目规模: 18 个 Maven 模块 / 9765 个 .java 文件 / 12611 个可见文件 / 218 MB
Steps to reproduce / 复现步骤
- 准备一个大型多模块 Maven 项目(约 1 万个
.java 文件)
- 确认项目根目录下已存在有效的
.lithe/run/generated.json(本例含 27 条配置)
- 打开该项目
- 项目树出现后立即点击工具栏的运行按钮
- 在弹出的"识别并生成"确认框中点击确认
Expected behavior / 预期行为
打开项目后数秒内,.lithe/run/generated.json 应被读取,Run 面板显示已有的 27 条运行配置。
如果配置尚未加载完成时用户点击了"识别并生成",应给出可见反馈(进度指示、提示,或等项目加载完成后自动执行),而不是静默丢弃这次操作。
Actual behavior / 实际行为
Run 面板持续显示"项目运行配置未找到"约 11 分钟,尽管 generated.json 一直存在且完全有效。这段时间内点击"识别并生成"并确认后没有任何反应:没有错误提示、没有进度指示、没有日志输出。约 11 分钟后配置自动出现,此后点击识别才生效。
定位到两处原因。
1. loadProjectServices 把 Spring 索引串在运行配置加载之前
// macos/Sources/Lithe/Models/AppModel/AppModel.swift:750
func loadProjectServices(at workspaceURL: URL, files: [URL]) async {
prepareJavaLanguageServerForWorkspaceIfNeeded(
at: workspaceURL,
files: files
)
await springFeature.load(
workspaceURL: workspaceURL,
files: files,
textOverrides: Dictionary(uniqueKeysWithValues: openDocuments.map {
($0.url.standardizedFileURL, $0.text)
})
)
guard let execution = await activateExecutionModule() else { return }
execution.tests.discover(workspaceURL: workspaceURL, files: files)
await execution.projectDevelopment.loadProject(at: workspaceURL, files: files)
}
最后一行才会走到 RunService.loadProject,而它负责把 configurationStatus 从 .missing 改成 .ready 并给 self.projectURL 赋值。这两件事都被压在 Spring 索引之后。Spring 索引在该项目上耗时 648 秒,见 #299。
需要强调:即使 Spring 索引被优化到几秒,这个串行耦合本身仍然是缺陷。它只是把不可用窗口从 11 分钟缩短到几秒,窗口依然存在,更大的项目或更慢的磁盘会让它重新变长。
2. generateRunConfigurations() 在项目未加载时静默返回
// macos/Sources/LitheExecutionModule/Services/RunService.swift:199
package func generateRunConfigurations() async {
guard let projectURL else { return }
RunService.reset() 在打开项目时把 projectURL 置为 nil。在窗口期内点击识别会命中这个 guard 直接返回,UI 侧无任何状态变化,用户无法区分"操作被丢弃"和"操作失败"。
这两点建议一并修复:只改顺序不改静默返回,窗口内点击仍然没有反馈;只改静默返回不改顺序,用户仍要等十几分钟。
Logs or diagnostic output / 日志或诊断输出
# 用 lithe-core release 构建针对目标项目实测各阶段耗时
workspace.snapshot: elapsed=256ms files=12611
spring.index: elapsed=648.09s ok=true
runConfig.inspect: elapsed=1.33s ok=true status="ready"
runConfig.resolve: elapsed=0.60s ok=true configurations=27
# inspect 返回的诊断
[{"code":"staleFingerprint","message":"Project inputs changed: 6 added, 0 removed, 47 modified"}]
Rust Core 侧读取配置完全正常:runConfig.inspect 返回 status: "ready",runConfig.resolve 返回 27 条配置。问题不在配置文件本身,也不在 Core,而在 macOS 侧的加载时序。
Checklist / 提交前检查
Platform / 平台
macOS
Lithe version / Lithe 版本
e19928bd(main)OS and architecture / 操作系统与架构
macOS 15.7.3, Apple Silicon (arm64)
Environment / 环境信息
Steps to reproduce / 复现步骤
.java文件).lithe/run/generated.json(本例含 27 条配置)Expected behavior / 预期行为
打开项目后数秒内,
.lithe/run/generated.json应被读取,Run 面板显示已有的 27 条运行配置。如果配置尚未加载完成时用户点击了"识别并生成",应给出可见反馈(进度指示、提示,或等项目加载完成后自动执行),而不是静默丢弃这次操作。
Actual behavior / 实际行为
Run 面板持续显示"项目运行配置未找到"约 11 分钟,尽管
generated.json一直存在且完全有效。这段时间内点击"识别并生成"并确认后没有任何反应:没有错误提示、没有进度指示、没有日志输出。约 11 分钟后配置自动出现,此后点击识别才生效。定位到两处原因。
1.
loadProjectServices把 Spring 索引串在运行配置加载之前最后一行才会走到
RunService.loadProject,而它负责把configurationStatus从.missing改成.ready并给self.projectURL赋值。这两件事都被压在 Spring 索引之后。Spring 索引在该项目上耗时 648 秒,见 #299。需要强调:即使 Spring 索引被优化到几秒,这个串行耦合本身仍然是缺陷。它只是把不可用窗口从 11 分钟缩短到几秒,窗口依然存在,更大的项目或更慢的磁盘会让它重新变长。
2.
generateRunConfigurations()在项目未加载时静默返回RunService.reset()在打开项目时把projectURL置为 nil。在窗口期内点击识别会命中这个 guard 直接返回,UI 侧无任何状态变化,用户无法区分"操作被丢弃"和"操作失败"。这两点建议一并修复:只改顺序不改静默返回,窗口内点击仍然没有反馈;只改静默返回不改顺序,用户仍要等十几分钟。
Logs or diagnostic output / 日志或诊断输出
Rust Core 侧读取配置完全正常:
runConfig.inspect返回status: "ready",runConfig.resolve返回 27 条配置。问题不在配置文件本身,也不在 Core,而在 macOS 侧的加载时序。Checklist / 提交前检查