Skip to content

Repository files navigation

Electron-XPC (Multi-Runtime) 框架 + Debug Panel

中文 | English

基于 Electron utilityProcess + MessageChannelMain 的生产级多进程 RPC 框架, 配套无侵入 Debug Panel(Ctrl+Shift+D 呼出)。

快速开始

npm install
npm run dev        # 开发模式(HMR,Debug Panel 自动挂载)
npm run build      # 产出 out/
npm run start      # 运行构建产物
npm run typecheck  # 类型检查

架构

Renderer                    Main                          Utility 进程池
───────                     ────                          ─────────────
client.download.start() ──► Gateway(ipcMain.handle) ──► RuntimeManager ──► [io-network]  DownloadModule
      │ (Proxy 自动注入 rt)    │ Debug 埋点                 │ 懒加载/熔断/心跳      │ MessageChannelMain 点对点
      │                      │                            └─► [native-heavy] ImageModule
      ▼                      ▼
onProgress(cb) ◄──────── EventRouter(精确订阅投递) ◄──────── emitEvent()(事件经 Port 上行)
                    DebugCollector ── xpc:debug:push ──► DebugPanel(仅推给订阅窗口)
  • 强类型契约:src/shared/protocol.ts 是单一数据源,前端调用具备完整 IDE 提示。
  • 信封协议:所有跨进程消息遵循 { type, id, module, method/…, payload },主进程只做路由中转,不执行业务。
  • 进程隔离:image.compress 崩溃不影响 download;Utility 之间禁止直连。

生产加固(相对"理想化模型"的 6 项修复)

# 问题 修复 位置
1 moduleRuntimeMap 手抄不同步 RUNTIME_OF_MODULE 与契约同文件,as const satisfies ModuleRuntimeMap 编译期强制同步 shared/protocol.ts
2 Port 假死 + 过期消息积压 请求携带 ts,Utility 引擎丢弃超 TTL(15s) 的积压请求;主进程 5s 心跳 ping、15s 无 pong 标记 unresponsive,恢复自动转绿 utility/engine.ts、main/runtime-manager.ts
3 事件广播泄漏/野指针 EventRouter:channel → webContentsId → 引用计数,无人订阅零开销;Preload 端 0→1 注册、1→0 注销;窗口销毁自动清理 main/gateway.ts、preload/index.ts
4 崩溃无限复活死循环 熔断器:60s 窗口内崩溃 ≥5 次拒绝重生,RPC 直接 reject 提示用户;主动 shutdown 不计崩溃 main/runtime-manager.ts
5 大数据序列化瓶颈 演示 allocNoise 返回 32MB ArrayBuffer 二进制直传(避免 base64 33% 膨胀);reply 预留 transfer 透传位 utility/modules/image.module.ts
6 调试黑盒 Debug Panel(订阅制推送)+ Utility console 重定向到主进程([xpc:xxx] 前缀)+ rpc_res 错误携带真实堆栈 + 三端 sourcemap debug-collector.ts、engine.ts

演示场景(App 界面按钮)

  • Start Download:RPC 路由到 io-network,进度事件流驱动进度条(Debug Panel 可见 RPC 日志与 download.progress 订阅计数)。
  • Alloc 32MB Binary:二进制直传性能演示。
  • 💥 Crash native-heavy:进程 exit(86) → pending 全部 reject → Panel 显示 🔴 crashed → 再次调用自动重生(连续 5 次触发熔断 ⛔)。
  • Block 2s / 17s:事件循环阻塞 → Panel 显示 🟠 unresponsive(心跳失联)→ 恢复转绿;17s 超过 TTL,主进程超时拒绝,阻塞期间排队的请求恢复后被 Utility 丢弃(主进程控制台可见"丢弃过期 RPC"日志)。

已知限制

  • Electron MessagePortMain.postMessage 的 transfer 列表仅支持转移 MessagePort 本身,不支持 ArrayBuffer 零拷贝转移(与浏览器 MessagePort 不同)。因此大数据优化采用原生二进制结构化克隆(相比 base64 字符串已省去 33% 膨胀与字符串编解码成本);需要真零拷贝时可评估 SharedArrayBuffer 共享内存。
  • Debug Panel 仅在开发环境挂载(import.meta.env.DEV)。

目录结构

src/
├── shared/
│   ├── protocol.ts          # 核心契约 + RUNTIME_OF_MODULE(单一数据源)
│   └── debug.ts             # Debug Panel 数据契约
├── main/
│   ├── index.ts             # 主进程入口
│   ├── runtime-manager.ts   # 进程池:懒加载/超时/崩溃恢复/熔断/心跳
│   ├── gateway.ts           # IPC 网关 + EventRouter 精确订阅
│   └── debug-collector.ts   # Debug 采集与订阅制推送
├── utility/
│   ├── engine.ts            # Utility 引擎:RPC 分发/TTL 丢弃/日志转发
│   ├── bootstrap-io.ts      # io-network 启动入口
│   ├── bootstrap-native.ts  # native-heavy 启动入口
│   └── modules/             # 业务模块(download / image)
├── preload/index.ts         # 安全桥接(xpc + xpcDebug)
└── renderer/
    ├── client.ts            # 强类型 Proxy 客户端
    ├── App.tsx              # 演示界面
    └── debug-panel/         # Debug Panel 组件

测试自动化

npm run test:smoke   # 无 GUI 冒烟自检:spawn/双 Runtime 路由/崩溃拒绝/自动重生,退出码报告
npm run test:e2e     # Python 编排器黑盒驱动真实构建产物(CDP + window.xpc 桥)

E2E 编排器(tests/)跑 5 个场景共 28 项断言:RPC 路由、事件流、崩溃恢复、二进制直传、 心跳/TTL/过期丢弃。确定性事实用普通断言;用例失败时才调用 TypeSafe Jev(System One) 做语义分诊——一次 system_one 往返同时问错误分类(Choice)、严重度(Score)、是否阻塞 合入(Noul),置信度 < 0.7 标记"需人工复核"而不是硬判。详见 tests/README.md。

License

MIT

About

Production-grade Electron multi-runtime RPC framework (utilityProcess + MessageChannelMain) with a built-in Debug Panel | 生产级 Electron 多进程 RPC 框架 + 调试面板

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages