application-packaging #4

Merged
202400507129 merged 9 commits from application-packaging into main 2026-09-08 17:05:03 +08:00
Owner
No description provided.
worker 崩溃遗留的持锁死行原先只在 manual+blocking 路径被回收,
后续 worker 遇死行一律让位 → 每 tick 抢锁失败、日志误报「手动分析占用中」。
acquire 现于类型判定前先做通用 stale 回收(任意获取方均可强抢死行),
tracker_worker 抢锁失败日志透出真实持锁方 kind/pid。全量 pytest 123 passed。
create_app(frontend_dir=...) 优先于 Settings.serve_frontend_dir(env YUJIAN_SERVE_FRONTEND);
目录含 index.html 才挂 StaticFiles(html=True) 于所有路由之后(不遮蔽 /api /docs /health),
未配置则维持纯 API(docker-nginx 形态不受影响)。新增 5 个托管/遮蔽/兜底测试。
- 新增 runtime_paths:app_root/data_dir 统一锚点——开发态=仓库根/backend/data,
  frozen(PyInstaller)=exe 同级/MediaCrawler-main 与 data/;config db 默认、crawler_runner/
  crawler_loader 的 MediaCrawler 定位全部改走该锚点(env 仍可覆盖)。
- 新增 launcher.py:argv 分发 server/worker 子命令,起服务前注入 MEDIA_CRAWLER_ROOT/
  YUJIAN_SERVE_FRONTEND_DIR 默认值(须在 import app.* 前),server 只绑 127.0.0.1。
- 修正 env 名:YUJIAN_SERVE_FRONTEND_DIR(pydantic-settings 去前缀后需与字段名逐字符一致)。
- 测试:test_runtime_paths(路径 frozen/开发态、launcher 分发与默认注入)+ P1 静态托管 5 例。
- packaging/yujian.spec:onedir 打包 launcher.py;hiddenimports 收 uvicorn/fastapi/app 全量
  + jieba/snownlp;collect_data_files 带 jieba 词典与 snownlp 语料(分词离线可用)。
- packaging/build.bat:pyinstaller 构建 + 复制前端 dist → exe 同级 webui/。
- launcher:YUJIAN_SERVE_FRONTEND_DIR 默认候选 webui/(frozen 分发件) → dist/(开发态)。
- .gitignore 忽略 dist-app/ 与 build/ 产物。
- 冒烟:frozen exe server→页面/JS/CSS/health 全 200 且同源托管 webui;worker 启动正常;
  jieba dict 随包确认;全量 pytest 无回归。
- 新增 app/services/launcher_open:open=端口占用则仅开浏览器(单实例不叠起);
  否则以同一入口拉起 server/worker 子进程(frozen=exe 自身)、写 <data>/yujian.pid、
  轮询就绪后开浏览器、阻塞至任一退出即优雅终止另一个;Ctrl+C 同路径收尾。
- stop=读 pid 文件终止 server/worker(crawler 孤儿由 crawl_gate stale 兜底 ≤75s)。
- YUJIAN_NO_BROWSER=1 禁用自动开浏览器(CI/自动化)。
- 测试 9 例(端口探测/self 命令 frozen-开发分支/pid 读写/单实例短路/stop);
  闭环冒烟:open→health 200→stop→端口关闭+pid 清除。全量 pytest 无回归。
- launcher main:server/worker/open/stop 前检测第三方依赖(pydantic_settings),
  缺失即打印改用 backend\.venv 的指引并退出 1,不再裸 traceback。
- 新增根目录 yujian.bat:自动定位 backend/.venv 的 python 转发参数
  (open/stop/server/worker/usage),作为双击/命令行应用入口。
- 闭环冒烟:仓库根 cwd 下 venv python open→health 200→stop 端口关闭+pid 清除。
- launcher main 空参数默认 = open(双击 yujian.exe 即单实例启动 server+worker 并开浏览器)。
- packaging/distribute.bat:组装绿色包到仓库同级目录(默认 <repo上级>/yujian-app):
  app bundle(_internal/yujian.exe) + 前端 dist→webui + MediaCrawler-main 整体拷贝
  (robocopy 排除各平台 Edge profile 缓存/组件 component_crx_cache、ProvenanceData、
  Cache、Code Cache 等与 docs/tests/.git)+ README.txt + 预建 data/。
- packaging/README.txt:绿色包中文使用说明(免安装、启动/停止、登录态说明)。
- .gitignore 收窄 dist-app*/ 通配。
- 后端新增 /api/app/shutdown(要求 X-Yujian-App 头,CSRF 轻防护):按
  <data>/yujian.pid 结束 worker + 触发已注册的 uvicorn 优雅退出钩子;非本地
  托管模式(dev/容器裸 uvicorn)不自杀并如实告知。
- launcher.run_server 改用 uvicorn.Server 显式持有并注册退出钩子
  (should_exit → 当前响应后优雅关闭;open 主进程随之清理 worker/pid)。
- 前端:Header 右侧「退出程序」按钮(退出图标+确认);成功后全屏遮罩提示
  「程序已退出,可关闭本页」;关闭时停掉跟踪轮询。
- 测试:app_control 4 例(缺头 403/空转 ok/pid kill/退出钩子调用);
  冒烟:dev open 模式 POST shutdown → serverStopped+workerStopped、端口关闭、
  pid 清除、launcher 收尾。前端 build 通过。
- 新增根级 build-app.bat:quick= npm run build + PyInstaller onedir
  → build\onedir\yujian\(yujian.exe+_internal+webui);full= 再组装
  MediaCrawler 运行时(排除浏览器缓存/组件)→ build\yujian-full\(发布包);
  clean= 清空 build\。
- packaging/build.bat、distribute.bat 改为薄转发到根 build-app.bat(/ full);
  yujian.spec 注释同步新入口与产物布局;.gitignore 增加根 build/。
- 重建 backend/.venv(旧 venv 遭批量文件删除损坏,备份在 %TEMP%\yujian-venv-broken-20260908);
  全量 pytest 通过;build/onedir 产物冒烟 health/root 200、stop 干净。
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
202400507129/yujian!4
No description provided.