Files
workutils/docs/superpowers/specs/2026-08-03-api-debug-proxy-startup-design.md
2026-08-03 10:42:20 +08:00

80 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WorkUtils API 本地调试代理启动设计
## 目标
WorkUtils 进程启动时自动启动 API 文档调试所需的本地 HTTP 代理。用户无需进入 API 导出页面、勾选复选框或点击导出按钮来启动代理。API 导出页面删除代理开关,并持续展示代理已启动或启动失败的只读状态。
## 范围
- 代理随 WorkUtils 的 `CommandLineRunner` 生命周期启动,GUI 和命令行入口使用同一套逻辑。
- 代理失败不得阻止 WorkUtils 主界面或命令行功能继续运行。
- API 导出始终读取应用启动阶段确定的代理端点;启动失败时端点为空,文档仍可导出,但接口调试功能不可用。
- WorkUtils 运行结束时主动停止 HTTP Server 和代理线程池。
- 不新增配置项,不持久化代理端口,不改变代理的随机本机端口策略。
## 架构
新增一个 Spring 单例生命周期服务,作为应用入口、API 插件和代理实现之间的唯一边界。服务负责:
1. 幂等启动 `DubboDebugProxy`;
2. 捕获启动异常并保存不可变状态;
3. 向 UI 和导出用例提供端点或失败原因;
4. 在应用运行结束时幂等关闭代理。
`WorkUtilsApplication.run(...)` 在分派 GUI 或命令行操作前调用生命周期服务的启动方法,并在运行结束的 `finally` 中关闭代理。这样代理会在任何 API 页面构造之前启动,也不会依赖可能晚于阻塞式窗口循环的 `ApplicationReadyEvent`。
`ApiDocPlugin` 注入同一个生命周期服务并传给 `ApiDocWindow`。页面只读取状态,不创建、重启或关闭代理。
## 状态模型
生命周期服务公开不可变状态,状态仅允许以下三种结果:
- `NOT_STARTED`:仅用于应用启动调用发生前和单元测试初始化;
- `RUNNING`:包含非空的 `http://127.0.0.1:{port}/dubbo/invoke` 地址;
- `FAILED`:包含可展示的失败原因,端点为空。
重复调用启动方法不得创建第二个代理实例。重复调用关闭方法不得抛出异常。
## API 导出页面
删除“启用接口调试(启动本地代理)”复选框。原位置显示只读状态标签:
- 成功:`● 本地代理已启动:http://127.0.0.1:{port}/dubbo/invoke`
- 失败:`● 本地代理启动失败:{错误原因}`
成功状态使用现有成功色,失败状态使用现有危险色。失败标签提供包含完整错误原因的 Tooltip 和 accessible text。状态标签不提供启动、重试或关闭操作。
## 导出数据流
`ApiDocExportRequest` 删除 `debugProxyEnabled` 字段和所有对应工厂参数。`RunApiDocExportUseCase` 每次执行都从注入的端点供应器读取当前地址,并将非空地址交给导出器。代理启动失败时供应器返回空字符串,导出照常进行,API 页面日志追加“本地代理不可用,导出文档的接口调试功能已禁用”。
页面不再持有代理复选框,也不再从 UI 控件构造代理选择状态。
## 代理关闭
`DubboDebugProxy` 增加幂等 `stop()`:停止 `HttpServer`,关闭其专用 `ExecutorService`。代理不复用全局任务执行器,防止关闭代理影响其他业务任务。
## 错误处理
- 启动失败:生命周期服务捕获异常、记录错误、保存 `FAILED` 状态,WorkUtils 继续运行。
- UI 展示:API 页面读取失败状态并展示短原因;完整原因放入 Tooltip。
- 导出降级:空端点不阻止 HTML/Markdown 生成,只禁用生成文档中的发送调试请求能力。
- 关闭失败:记录警告,不覆盖原始业务异常,也不阻止进程退出。
## 测试策略
- 生命周期服务:启动成功、启动失败、重复启动、重复关闭、关闭释放代理。
- 应用架构:`WorkUtilsApplication` 在业务分派前启动,并在 `finally` 中关闭。
- API 页面:不存在代理复选框;成功和失败状态文案、颜色语义、Tooltip 与 accessible text 正确。
- 导出请求:三个模式不再接收或保存代理布尔值。
- 导出用例:成功时始终传递代理地址;失败时传递空地址且导出仍执行。
- 聚焦测试后运行 Maven 全量测试、编译和 `git diff --check`。
## 验收标准
1. 启动 WorkUtils 后,无需打开 API 导出页面即可在日志中看到本地代理启动地址。
2. API 导出页没有代理复选框,仅显示已启动或失败状态。
3. 代理成功时,任何 API 导出都自动获得代理地址。
4. 代理失败时,WorkUtils 和普通文档导出仍可使用,页面清楚提示调试功能不可用。
5. WorkUtils 运行结束时代理端口和线程池被主动释放。