Skip to content

fix(desktop): 消息通道面板把外部启动的实例识别为运行中 - #830

Open
leonsong09 wants to merge 1 commit into
lsdefine:mainfrom
leonsong09:fix/desktop-panel-external-instance
Open

leonsong09 wants to merge 1 commit into
lsdefine:mainfrom
leonsong09:fix/desktop-panel-external-instance

Conversation

@leonsong09

Copy link
Copy Markdown

问题

桌面版「消息通道」页面里,明明在跑的通道(fsapp / tgapp / dcapp / qqapp / dingtalkapp)显示为离线,只有壳自己拉起的才显示在线。

原因:ServiceManager._state() 里 running 只认 owned(本 bridge spawn 的进程);另一条 external 判据要求目录项带 port,而 discover_im_services() 只给 conductor 声明了端口,IM 通道既无端口也无 pidfile,于是凡是由仓库侧 App Manager / schtasks / 终端启动的实例,一律被判 offline。

复现(Windows 便携版 v0.2.8 + 仓库侧运行 fsapp/tgapp):

GET /services/panel
{"id": "frontends/fsapp.py", "status": "offline", "running": false, "owned": false, "external": false}

改动

  • discover_im_services() / discover_extra_services():目录项增加 script 字段,供进程匹配使用。
  • 新增 _external_proc_pids() 等辅助:用 psutil 扫描全部进程的 cmdline,按脚本路径子串匹配找出“外部实例”,结果 3s 缓存(所有服务共用一次 sweep,未装 psutil 时自动退化为不做外部检测,不影响原有行为)。
  • _state():命中外部实例时 status/running = 运行中、回填 pid,并新增 externalProc 字段区分“外部实例”(external/portConflict 语义保持不变)。
  • start_service():发现外部实例时返回 already_running_external,避免重复拉起——fsapp.py 没有单实例锁(tgapp/dcapp/qqapp/dingtalkapp 有 ensure_single_instance,wecomapp/fsapp 没有),重复启动会双开并重复收发消息。
  • stop_service(include_external=):仅 HTTP 停止入口传 True;退出壳 / stop_all_extras 保持 False,绝不误杀不属于本桥的进程。

实测

  • 面板:fsapp / tgapp / reflect/scheduler.py 由“离线”变为“在线”,externalProc=true、pid 正确。
  • 对已在外部运行的通道调用 POST /services/start → 400 {"ok": false, "error": "already_running_external", "service": {..., "lastError": "already running outside this bridge (pid 30492)"}}。
  • py_compile 通过;未改动既有接口契约,纯新增字段。

Co-Authored-By: GenericAgent bot@gaagent.ai

面板原先只把 bridge 自己 spawn 的进程算作 running(_state 里 owned),而目录里
只有 conductor 带 port 可探活,fsapp/tgapp/dcapp 等 IM 通道既无端口也无 pidfile,
于是由仓库侧 App Manager / schtasks / 终端启动的实例一律显示"离线"。

- discover_im_services / discover_extra_services: 目录项增加 script 字段
- 新增 psutil 全进程 cmdline 扫描(3s 缓存,全服务共用一次 sweep)判定外部实例:
  命中则 status/running=在线、回填 pid,并新增 externalProc 字段区分"外部实例"
- start_service: 发现外部实例时返回 already_running_external,避免重复拉起
  (fsapp.py 无单实例锁,重复启动会双开重复收发消息)
- stop_service(include_external=): 仅 HTTP 停止入口传 True;退出壳 / stop_all_extras
  仍保持 False,绝不误杀不属于本桥的进程

实测(Windows 便携版 v0.2.8 + 仓库侧运行的 fsapp/tgapp):面板由"离线"变为"在线",
externalProc=true、pid 正确;对已在外部运行的通道点启动返回 400 already_running_external。

Co-Authored-By: GenericAgent <bot@gaagent.ai>
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