🐛 fix(deploy): 修干净机器首次构建两处必挂——.dockerignore 排除 deploy/ + celery 并行构建依赖
部署机首次 docker compose up -d 实测暴露: - .dockerignore 自"重写独立dockerfile"起排除整个 deploy/,而 Dockerfile.frontend COPY deploy/nginx/frontend.conf、Dockerfile.moldinsight COPY deploy/requirements-*.txt → COPY not found。历史一直有旧镜像兜底未暴露; BuildKit 不支持重包含被排除目录的子文件,直接移除该行 - Dockerfile.celery FROM gemold-backend:latest 在 compose 并行构建下引用 尚不存在的本地镜像必挂 → 删除 Dockerfile.celery,moldinsight-celery 改为 与 API 服务同一 build 声明 + 同一 gemold-backend:latest tag(compose 去重 只构建一次),celery 仅以 command: 覆盖启动 worker,参数语义不变 - build.sh/.bat 移除 gemold-celery 构建步骤;OPERATIONS / OCC_THROUGHPUT / TECH_DEBT / .env.example 的 Dockerfile.celery 指向同步改写;STATUS 补录 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
+2
-1
@@ -53,7 +53,8 @@ tmp/
|
|||||||
# Docker
|
# Docker
|
||||||
Dockerfile*
|
Dockerfile*
|
||||||
docker-compose*.yml
|
docker-compose*.yml
|
||||||
deploy/
|
# 注意:deploy/ 不能排除——Dockerfile.moldinsight COPY deploy/requirements-*.txt、
|
||||||
|
# Dockerfile.frontend COPY deploy/nginx/frontend.conf,排除会让干净机器首次构建必挂
|
||||||
|
|
||||||
# 其他
|
# 其他
|
||||||
.trae/
|
.trae/
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ LLM_MODEL=gpt-4o-mini
|
|||||||
LLM_TIMEOUT=60
|
LLM_TIMEOUT=60
|
||||||
LLM_MAX_TOKENS=2000
|
LLM_MAX_TOKENS=2000
|
||||||
|
|
||||||
# Celery/OCC 吞吐调优(可选,默认值见 deploy/Dockerfile.celery;
|
# Celery/OCC 吞吐调优(可选,默认值在 compose 的 ${CELERY_CONCURRENCY:-2};
|
||||||
# concurrency 即 OCC 并行分析数,见 docs/topics/performance/OCC_THROUGHPUT.md)
|
# concurrency 即 OCC 并行分析数,见 docs/topics/performance/OCC_THROUGHPUT.md)
|
||||||
# CELERY_CONCURRENCY=2
|
# CELERY_CONCURRENCY=2
|
||||||
# CELERY_MAX_TASKS_PER_CHILD=50
|
# CELERY_MAX_TASKS_PER_CHILD=50
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
# Celery Worker 与 unified 后端共用同一运行时镜像(自包含,批次 1 起)。
|
|
||||||
# 此前 FROM gemold-moldinsight:latest 与 compose/build.sh 构建的
|
|
||||||
# gemold-backend:latest 不一致,干净环境下 celery 镜像构建必然失败。
|
|
||||||
FROM gemold-backend:latest
|
|
||||||
|
|
||||||
# OCC 并行度伸缩(OCC_THROUGHPUT 方案 A,见 docs/topics/performance/OCC_THROUGHPUT.md):
|
|
||||||
# 每个 prefork 子进程各持一个串行 OCC 通道,concurrency 即并行分析数
|
|
||||||
# (调大时预算好每子进程内存与 PG 连接数);max-tasks-per-child 让子进程
|
|
||||||
# 定期重启,兜底回收 OCC 超时后滞留的线程。可在 compose/.env 覆盖。
|
|
||||||
ENV CELERY_CONCURRENCY=2 \
|
|
||||||
CELERY_MAX_TASKS_PER_CHILD=50
|
|
||||||
|
|
||||||
# sh -c + exec:既支持环境变量替换,又让 celery exec 接管 PID 1 正确接收 SIGTERM
|
|
||||||
CMD ["sh", "-c", "exec celery -A celery_app worker --workdir=/app/src --concurrency=${CELERY_CONCURRENCY:-2} --max-tasks-per-child=${CELERY_MAX_TASKS_PER_CHILD:-50} --loglevel=info"]
|
|
||||||
@@ -11,11 +11,6 @@ echo.
|
|||||||
echo === 构建统一后端镜像 ===
|
echo === 构建统一后端镜像 ===
|
||||||
docker build -t gemold-backend:latest -f deploy\Dockerfile.moldinsight .
|
docker build -t gemold-backend:latest -f deploy\Dockerfile.moldinsight .
|
||||||
|
|
||||||
echo.
|
|
||||||
echo === 构建 Celery Worker 镜像 ===
|
|
||||||
docker build -t gemold-celery:latest -f deploy\Dockerfile.celery .
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo.
|
echo.
|
||||||
echo === 构建前端镜像 (Nginx 静态站点) ===
|
echo === 构建前端镜像 (Nginx 静态站点) ===
|
||||||
docker build -t gemold-frontend:latest -f deploy\Dockerfile.frontend .
|
docker build -t gemold-frontend:latest -f deploy\Dockerfile.frontend .
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ echo ""
|
|||||||
echo "=== 构建统一后端镜像 ==="
|
echo "=== 构建统一后端镜像 ==="
|
||||||
docker build -t gemold-backend:latest -f deploy/Dockerfile.moldinsight .
|
docker build -t gemold-backend:latest -f deploy/Dockerfile.moldinsight .
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== 构建 Celery Worker 镜像 ==="
|
|
||||||
docker build -t gemold-celery:latest -f deploy/Dockerfile.celery .
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== 构建前端镜像 (Nginx 静态站点) ==="
|
echo "=== 构建前端镜像 (Nginx 静态站点) ==="
|
||||||
|
|||||||
@@ -5,12 +5,10 @@
|
|||||||
#
|
#
|
||||||
# 服务清单:moldinsight(独立 API)+ moldinsight-celery(异步分析 worker)
|
# 服务清单:moldinsight(独立 API)+ moldinsight-celery(异步分析 worker)
|
||||||
# 不含前端、不含 inventory。
|
# 不含前端、不含 inventory。
|
||||||
|
# 镜像:两服务共用 gemold-backend:latest(同一 build 声明,compose 只构建一次;
|
||||||
|
# celery 仅以 command 覆盖启动 worker),无跨镜像构建依赖,干净机器裸 up 一把过。
|
||||||
# 注意:服务未声明 profiles(避免裸 up 报 "no service selected"),
|
# 注意:服务未声明 profiles(避免裸 up 报 "no service selected"),
|
||||||
# 模式切换唯一入口是 -f 文件名。
|
# 模式切换唯一入口是 -f 文件名。
|
||||||
#
|
|
||||||
# 镜像说明:本文件里 moldinsight service 的 image 固定为 gemold-backend:latest,
|
|
||||||
# 与 deploy/Dockerfile.celery 的 FROM gemold-backend:latest 对齐;只要 build.sh
|
|
||||||
# 执行过(或已存在该 tag),celery 镜像就能正常构建,不再依赖 gemold-moldinsight tag。
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# 公共环境变量(moldinsight 家族共用)
|
# 公共环境变量(moldinsight 家族共用)
|
||||||
@@ -54,8 +52,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: deploy/Dockerfile.moldinsight
|
dockerfile: deploy/Dockerfile.moldinsight
|
||||||
# 与 Dockerfile.celery 的 FROM 对齐;统一用 gemold-backend tag,避免历史
|
# 统一用 gemold-backend tag(历史 gemold-moldinsight:latest 双 tag 已废弃)
|
||||||
# gemold-moldinsight:latest / gemold-backend:latest 双 tag 漂移
|
|
||||||
image: gemold-backend:latest
|
image: gemold-backend:latest
|
||||||
container_name: gemold_moldinsight
|
container_name: gemold_moldinsight
|
||||||
command: ["python", "-m", "uvicorn", "entrypoints.moldinsight:app", "--host", "0.0.0.0", "--port", "8000"]
|
command: ["python", "-m", "uvicorn", "entrypoints.moldinsight:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
@@ -80,13 +77,16 @@ services:
|
|||||||
- gemold_network
|
- gemold_network
|
||||||
|
|
||||||
moldinsight-celery:
|
moldinsight-celery:
|
||||||
|
# 与 moldinsight 共用同一镜像,仅 command 覆盖启动 worker
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: deploy/Dockerfile.celery
|
dockerfile: deploy/Dockerfile.moldinsight
|
||||||
|
image: gemold-backend:latest
|
||||||
container_name: gemold_celery
|
container_name: gemold_celery
|
||||||
|
command: ["sh", "-c", "exec celery -A celery_app worker --workdir=/app/src --concurrency=${CELERY_CONCURRENCY:-2} --max-tasks-per-child=${CELERY_MAX_TASKS_PER_CHILD:-50} --loglevel=info"]
|
||||||
environment:
|
environment:
|
||||||
<<: *base_env
|
<<: *base_env
|
||||||
# Celery/OCC 吞吐调优(OCC_THROUGHPUT 方案 A,默认值在 Dockerfile.celery)
|
# Celery/OCC 吞吐调优(OCC_THROUGHPUT 方案 A)
|
||||||
CELERY_CONCURRENCY: ${CELERY_CONCURRENCY:-2}
|
CELERY_CONCURRENCY: ${CELERY_CONCURRENCY:-2}
|
||||||
CELERY_MAX_TASKS_PER_CHILD: ${CELERY_MAX_TASKS_PER_CHILD:-50}
|
CELERY_MAX_TASKS_PER_CHILD: ${CELERY_MAX_TASKS_PER_CHILD:-50}
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
+8
-3
@@ -12,7 +12,7 @@
|
|||||||
# 旧 --profile 写法不再是模式开关,模式切换唯一入口是 -f 文件名。
|
# 旧 --profile 写法不再是模式开关,模式切换唯一入口是 -f 文件名。
|
||||||
#
|
#
|
||||||
# 服务清单:frontend + backend(unified 入口) + moldinsight-celery
|
# 服务清单:frontend + backend(unified 入口) + moldinsight-celery
|
||||||
# 镜像构建顺序由 deploy/build.sh 保证(base → backend → frontend,celery 复用 backend)
|
# 镜像:gemold-backend / gemold-frontend(celery 复用 gemold-backend,仅 command 不同)
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# 公共环境变量(moldinsight 家族 backend/celery/moldinsight 共用)
|
# 公共环境变量(moldinsight 家族 backend/celery/moldinsight 共用)
|
||||||
@@ -96,13 +96,18 @@ services:
|
|||||||
- gemold_network
|
- gemold_network
|
||||||
|
|
||||||
moldinsight-celery:
|
moldinsight-celery:
|
||||||
|
# 与 backend 共用同一镜像(同一 build 声明 + 同一 tag,compose 只构建一次),
|
||||||
|
# 仅以 command 覆盖启动 worker——消除旧 Dockerfile.celery(已删)FROM
|
||||||
|
# gemold-backend 在并行构建下的"镜像尚不存在"陷阱,干净机器裸 up 一把过
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: deploy/Dockerfile.celery
|
dockerfile: deploy/Dockerfile.moldinsight
|
||||||
|
image: gemold-backend:latest
|
||||||
container_name: gemold_celery
|
container_name: gemold_celery
|
||||||
|
command: ["sh", "-c", "exec celery -A celery_app worker --workdir=/app/src --concurrency=${CELERY_CONCURRENCY:-2} --max-tasks-per-child=${CELERY_MAX_TASKS_PER_CHILD:-50} --loglevel=info"]
|
||||||
environment:
|
environment:
|
||||||
<<: *base_env
|
<<: *base_env
|
||||||
# Celery/OCC 吞吐调优(OCC_THROUGHPUT 方案 A,默认值在 Dockerfile.celery)
|
# Celery/OCC 吞吐调优(OCC_THROUGHPUT 方案 A)
|
||||||
CELERY_CONCURRENCY: ${CELERY_CONCURRENCY:-2}
|
CELERY_CONCURRENCY: ${CELERY_CONCURRENCY:-2}
|
||||||
CELERY_MAX_TASKS_PER_CHILD: ${CELERY_MAX_TASKS_PER_CHILD:-50}
|
CELERY_MAX_TASKS_PER_CHILD: ${CELERY_MAX_TASKS_PER_CHILD:-50}
|
||||||
# uploads_data 共享卷(D6 过渡兜底):RustFS 异常时 worker 回退本地路径下载。
|
# uploads_data 共享卷(D6 过渡兜底):RustFS 异常时 worker 回退本地路径下载。
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ uvicorn src.entrypoints.moldinsight:app --reload --host 0.0.0.0 --port 8000
|
|||||||
uvicorn src.entrypoints.inventory:app --reload --host 0.0.0.0 --port 8001
|
uvicorn src.entrypoints.inventory:app --reload --host 0.0.0.0 --port 8001
|
||||||
```
|
```
|
||||||
|
|
||||||
Celery worker(moldinsight 异步分析链路;本地从 `src` 目录跑,与 [deploy/Dockerfile.celery](../deploy/Dockerfile.celery) CMD 同参):
|
Celery worker(moldinsight 异步分析链路;本地从 `src` 目录跑,与 compose 中 `moldinsight-celery` 的 `command:` 覆盖同参——worker 与后端共用 `gemold-backend` 镜像,无独立 Dockerfile):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src && celery -A celery_app worker --concurrency=2 --loglevel=info
|
cd src && celery -A celery_app worker --concurrency=2 --loglevel=info
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
> 维护规则:每完整完成一个需求,**倒序在本文顶部加一条**(日期 + 主题 + 关键事实);其余主文档(架构 / 规划 / 技术债 / 部署)维护各自的"当前有效说法",本文只记录"什么时候做到了哪一步"。维护规则出处见根目录 [AGENTS.md](../AGENTS.md)。
|
> 维护规则:每完整完成一个需求,**倒序在本文顶部加一条**(日期 + 主题 + 关键事实);其余主文档(架构 / 规划 / 技术债 / 部署)维护各自的"当前有效说法",本文只记录"什么时候做到了哪一步"。维护规则出处见根目录 [AGENTS.md](../AGENTS.md)。
|
||||||
> 早期条目(2026-09-17 之前)已精简为锚点,完整流水见 [archive/2026-09_governance_batches.md](archive/2026-09_governance_batches.md) 与 [archive/2026-09_status_history.md](archive/2026-09_status_history.md)。
|
> 早期条目(2026-09-17 之前)已精简为锚点,完整流水见 [archive/2026-09_governance_batches.md](archive/2026-09_governance_batches.md) 与 [archive/2026-09_status_history.md](archive/2026-09_status_history.md)。
|
||||||
|
|
||||||
> 2026-09-24(**Compose 按部署模式拆分为三个一键文件 + 文档全量同步**:① 单文件 profile 编排拆为"模式 ↔ 文件名"一一对应的三文件——[docker-compose.yml](../docker-compose.yml)(unified 默认入口:frontend + backend + moldinsight-celery,`docker compose up -d` 即起)+ [docker-compose.moldinsight.yml](../docker-compose.moldinsight.yml)(moldinsight-only:独立 API + celery)+ [docker-compose.inventory.yml](../docker-compose.inventory.yml)(inventory-only:仅 inventory,不声明任何命名卷避免空卷);② **服务不再声明 `profiles`**——compose 规则是声明了 profiles 的服务在裸 `up` 下不会被选中(拆分首版保留 profiles 导致裸 `up` / 裸 `-f` 均报 `no service selected`,部署机实测暴露后移除),模式切换唯一入口是 `-f` 文件名,历史 `--profile full/moldinsight/inventory` 写法随拆分失效(其目标服务本就已移出默认文件,兼容无意义);③ **顺手修复两个既有部署隐患**——moldinsight-only 场景 celery 的 `depends_on` 悬空(原指向被 profile 过滤掉的 `backend`,现各文件内分别指向 `backend` / `moldinsight`),以及 `gemold-moldinsight:latest` 与 `gemold-backend:latest` 双 tag 漂移(moldinsight service 的 image 统一为 `gemold-backend:latest`,与 [Dockerfile.celery](../deploy/Dockerfile.celery) 的 FROM 对齐,干净环境单跑 moldinsight-only 不再构建失败);④ `gemold_network` / `uploads_data` / `html_data` 加 `name:` 固定命名,跨文件 / 跨模式可复用;每文件内部以 YAML anchor(`x-base-env`)收敛 35+ 行重复 environment,`SECRET_KEY` / `ADMIN_PASSWORD` 的 `${VAR:?}` fail-fast 校验保留;⑤ 文档同步 11 文件:[DEPLOYMENT.md](DEPLOYMENT.md) §1.1 新增一键部署总表 + §2 三模式各附文件名与一键命令,[deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md) §6/§11 重写,[README.md](../README.md) 快速开始与 Compose 入口、[OPERATIONS.md](OPERATIONS.md) §4、[deploy/build.sh](../deploy/build.sh) / [.bat](../deploy/build.bat) 末尾提示、PORT_CONFIG / DEPLOY_PORT / STORAGE_SETUP / frontend/README 链接全部对齐(`AGENTS.md` §4.1 部署方式→DEPLOYMENT 同步规则满足)。**验证**:三文件 YAML 解析 + 结构静态校验通过(services / depends_on / 卷声明 / anchor 合并 / 网络命名 / 无 profiles 残留);5 个 service 的 environment 键与拆分前逐一比对(YAML 展开合并键后 39/39、34/34、39/39、34/34、20/20)零丢失。**遗留**:`docker compose -f <file> config` 干跑与真实 up 待部署机执行。)
|
> 2026-09-24(**Compose 按部署模式拆分为三个一键文件 + 文档全量同步**:① 单文件 profile 编排拆为"模式 ↔ 文件名"一一对应的三文件——[docker-compose.yml](../docker-compose.yml)(unified 默认入口:frontend + backend + moldinsight-celery,`docker compose up -d` 即起)+ [docker-compose.moldinsight.yml](../docker-compose.moldinsight.yml)(moldinsight-only:独立 API + celery)+ [docker-compose.inventory.yml](../docker-compose.inventory.yml)(inventory-only:仅 inventory,不声明任何命名卷避免空卷);② **服务不再声明 `profiles`**——compose 规则是声明了 profiles 的服务在裸 `up` 下不会被选中(拆分首版保留 profiles 导致裸 `up` / 裸 `-f` 均报 `no service selected`,部署机实测暴露后移除),模式切换唯一入口是 `-f` 文件名,历史 `--profile full/moldinsight/inventory` 写法随拆分失效(其目标服务本就已移出默认文件,兼容无意义);③ **顺手修复两个既有部署隐患**——moldinsight-only 场景 celery 的 `depends_on` 悬空(原指向被 profile 过滤掉的 `backend`,现各文件内分别指向 `backend` / `moldinsight`),以及 `gemold-moldinsight:latest` 与 `gemold-backend:latest` 双 tag 漂移(moldinsight service 的 image 统一为 `gemold-backend:latest`,与 [Dockerfile.celery](../deploy/Dockerfile.celery) 的 FROM 对齐,干净环境单跑 moldinsight-only 不再构建失败);④ `gemold_network` / `uploads_data` / `html_data` 加 `name:` 固定命名,跨文件 / 跨模式可复用;每文件内部以 YAML anchor(`x-base-env`)收敛 35+ 行重复 environment,`SECRET_KEY` / `ADMIN_PASSWORD` 的 `${VAR:?}` fail-fast 校验保留;⑤ 文档同步 11 文件:[DEPLOYMENT.md](DEPLOYMENT.md) §1.1 新增一键部署总表 + §2 三模式各附文件名与一键命令,[deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md) §6/§11 重写,[README.md](../README.md) 快速开始与 Compose 入口、[OPERATIONS.md](OPERATIONS.md) §4、[deploy/build.sh](../deploy/build.sh) / [.bat](../deploy/build.bat) 末尾提示、PORT_CONFIG / DEPLOY_PORT / STORAGE_SETUP / frontend/README 链接全部对齐(`AGENTS.md` §4.1 部署方式→DEPLOYMENT 同步规则满足);⑥ **部署机首次实测再暴露并修复两个干净机器构建必挂点**——(a) [.dockerignore](../.dockerignore) 自"重写独立dockerfile"起排除整个 `deploy/`,而 Dockerfile.frontend 要 COPY `deploy/nginx/frontend.conf`、Dockerfile.moldinsight 要 COPY `deploy/requirements-*.txt`(历史一直有旧镜像兜底未暴露;BuildKit 不支持重包含被排除目录的子文件,直接移除该行,deploy/ 仅几 KB 无上下文负担);(b) `Dockerfile.celery` `FROM gemold-backend:latest` 在 compose 并行构建下引用尚不存在的本地镜像必挂——**删除 Dockerfile.celery**,`moldinsight-celery` 改为与 API 服务**同一 build 声明 + 同一 `gemold-backend:latest` tag**(compose 去重只构建一次),celery 仅以 `command:` 覆盖启动 worker(`--concurrency` / `--max-tasks-per-child` 参数经 compose 命令与 `.env` 透传,语义不变),build.sh/.bat 移除 gemold-celery 构建步骤,OPERATIONS / OCC_THROUGHPUT / TECH_DEBT / .env.example 的 Dockerfile.celery 指向同步改写。**验证**:三文件 YAML 解析 + 结构静态校验通过(services / depends_on / 卷声明 / anchor 合并 / 网络命名 / 无 profiles 残留 / celery 与 API 服务 build 声明一致性);5 个 service 的 environment 键与拆分前逐一比对(YAML 展开合并键后 39/39、34/34、39/39、34/34、20/20)零丢失。**遗留**:部署机 `git pull` 后裸 `docker compose up -d` 端到端复验;base 镜像(miniconda3 / node / nginx)拉取依赖 docker.io 连通性,不通时需配镜像加速。
|
||||||
>
|
>
|
||||||
> 2026-09-24(**D17 Human-in-Loop 老师傅经验反馈批 3 上线(前端按钮 + Dialog + 经验角标)——闭环可视**:① [ResultView.vue:35-47](frontend/src/modules/moldinsight/ResultView.vue#L35-L47) 方案卡片 summary-header 加 `t-tag theme="success" variant="light"` 经验角标("📚 历史经验 N 条"),从 `hintsByAxis[currentAxisHint]` 读取,按 scheme_axis 索引,无 hints 时不渲染;② [ResultView.vue:131-138](frontend/src/modules/moldinsight/ResultView.vue#L131-L138) `export-buttons-bar` 加 `👍 老师傅反馈` 按钮(`v-if="canGiveFeedback"` 角色门控:admin 或 process_engineer);③ 新建 [components/HumanFeedbackDialog.vue](frontend/src/modules/moldinsight/components/HumanFeedbackDialog.vue):t-dialog + t-form + t-radio-group 三选一(采纳 / 建议调整 / 拒绝)+ t-textarea 原因 + 调整建议(仅 adjust 模式显隐);提交走 `moldinsightApi.submitExperienceFeedback`,成功后 emit `submitted` 让父组件重拉 hints 刷新角标;④ [shared/api-client.ts:407-444](frontend/src/shared/api-client.ts#L407-L444) `moldinsightApi` 新增 `getExperienceHints` / `submitExperienceFeedback` 两个方法(生成类型由 openapi-typescript 自动产出);⑤ [ResultView.vue](frontend/src/modules/moldinsight/ResultView.vue) `onMounted` 调 `loadExperienceHints` 拉一次 + 反馈提交后 `onFeedbackSubmitted` 再拉一次(写入即消费前端可见);`canGiveFeedback` 走 `is_superuser || roles 含 process_engineer` 表达式(项目硬规则"前端不要破坏 ResultView.vue 视觉一致性":按钮与既有 6 个 t-button 同一 `export-buttons-bar`,theme/size 一致;角标 theme="success" variant="light" 与既有 t-tag theme="primary" / "warning" 同款)。**接口变更三件套随批完成**:openapi.json 重导出(2 个新 path,含 ExperienceFeedbackCreate / ExperienceHintItem / ExperienceHintsResponse 三个新 schema)→ `npm run gen:api` 再生 types/api.ts → `npm run build` 通过。**后端基线**:**192 passed, 13 skipped**(批 3 不改后端);**前端构建**:vue-tsc + vite 通过,ResultView 包大小 37.18 kB / 11.91 kB gzip。**D17 闭环端到端可用**:admin / process_engineer 在 ResultView 点"👍 老师傅反馈" → Dialog 选"采纳"+ 写原因 → 提交 → 角标即时刷新(重拉 hints);下次同指纹 STP 分析,`PartingCandidateGenerator` 候选方向加成 + `PartingSchemeScorer` total_score 加成 + method 标签升级 `human_experience_primary`。**下一步**:批 4(衰减机制完善 + DFM 规则库独立模块化 + 经验冲突仲裁 UI)按需排期。)
|
> 2026-09-24(**D17 Human-in-Loop 老师傅经验反馈批 3 上线(前端按钮 + Dialog + 经验角标)——闭环可视**:① [ResultView.vue:35-47](frontend/src/modules/moldinsight/ResultView.vue#L35-L47) 方案卡片 summary-header 加 `t-tag theme="success" variant="light"` 经验角标("📚 历史经验 N 条"),从 `hintsByAxis[currentAxisHint]` 读取,按 scheme_axis 索引,无 hints 时不渲染;② [ResultView.vue:131-138](frontend/src/modules/moldinsight/ResultView.vue#L131-L138) `export-buttons-bar` 加 `👍 老师傅反馈` 按钮(`v-if="canGiveFeedback"` 角色门控:admin 或 process_engineer);③ 新建 [components/HumanFeedbackDialog.vue](frontend/src/modules/moldinsight/components/HumanFeedbackDialog.vue):t-dialog + t-form + t-radio-group 三选一(采纳 / 建议调整 / 拒绝)+ t-textarea 原因 + 调整建议(仅 adjust 模式显隐);提交走 `moldinsightApi.submitExperienceFeedback`,成功后 emit `submitted` 让父组件重拉 hints 刷新角标;④ [shared/api-client.ts:407-444](frontend/src/shared/api-client.ts#L407-L444) `moldinsightApi` 新增 `getExperienceHints` / `submitExperienceFeedback` 两个方法(生成类型由 openapi-typescript 自动产出);⑤ [ResultView.vue](frontend/src/modules/moldinsight/ResultView.vue) `onMounted` 调 `loadExperienceHints` 拉一次 + 反馈提交后 `onFeedbackSubmitted` 再拉一次(写入即消费前端可见);`canGiveFeedback` 走 `is_superuser || roles 含 process_engineer` 表达式(项目硬规则"前端不要破坏 ResultView.vue 视觉一致性":按钮与既有 6 个 t-button 同一 `export-buttons-bar`,theme/size 一致;角标 theme="success" variant="light" 与既有 t-tag theme="primary" / "warning" 同款)。**接口变更三件套随批完成**:openapi.json 重导出(2 个新 path,含 ExperienceFeedbackCreate / ExperienceHintItem / ExperienceHintsResponse 三个新 schema)→ `npm run gen:api` 再生 types/api.ts → `npm run build` 通过。**后端基线**:**192 passed, 13 skipped**(批 3 不改后端);**前端构建**:vue-tsc + vite 通过,ResultView 包大小 37.18 kB / 11.91 kB gzip。**D17 闭环端到端可用**:admin / process_engineer 在 ResultView 点"👍 老师傅反馈" → Dialog 选"采纳"+ 写原因 → 提交 → 角标即时刷新(重拉 hints);下次同指纹 STP 分析,`PartingCandidateGenerator` 候选方向加成 + `PartingSchemeScorer` total_score 加成 + method 标签升级 `human_experience_primary`。**下一步**:批 4(衰减机制完善 + DFM 规则库独立模块化 + 经验冲突仲裁 UI)按需排期。)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -145,7 +145,7 @@
|
|||||||
- 顺带删除:内存形状缓存链(`_cache_export_shapes` / `get_export_shapes` / `_persist_step_exports`)、`CADExporter.export_mold_results`(零调用方)、shape_loader(→ [stp_materializer.py](../src/moldinsight/services/stp_materializer.py))
|
- 顺带删除:内存形状缓存链(`_cache_export_shapes` / `get_export_shapes` / `_persist_step_exports`)、`CADExporter.export_mold_results`(零调用方)、shape_loader(→ [stp_materializer.py](../src/moldinsight/services/stp_materializer.py))
|
||||||
- 回归测试:[tests/test_occ_process_pool.py](../tests/test_occ_process_pool.py)(OCC-gated,6 例含真实盒体 STP 端到端)
|
- 回归测试:[tests/test_occ_process_pool.py](../tests/test_occ_process_pool.py)(OCC-gated,6 例含真实盒体 STP 端到端)
|
||||||
|
|
||||||
**方案 A 部署参数落地**(2026-09-18):`CELERY_CONCURRENCY` / `CELERY_MAX_TASKS_PER_CHILD` 进 [Dockerfile.celery](../deploy/Dockerfile.celery) + compose + `.env.example`(`--max-tasks-per-child` 仍保留为进程回收兜底)。
|
**方案 A 部署参数落地**(2026-09-18):`CELERY_CONCURRENCY` / `CELERY_MAX_TASKS_PER_CHILD` 进 compose + `.env.example`(`--max-tasks-per-child` 仍保留为进程回收兜底;2026-09-24 起 worker 与后端共用 `gemold-backend` 镜像,Dockerfile.celery 已移除,参数经 compose `command:` 覆盖与环境变量传递)。
|
||||||
|
|
||||||
保留为已知约束(非待修缺陷):
|
保留为已知约束(非待修缺陷):
|
||||||
- 单进程内 OCC 串行是正确性要求(OCC 非线程安全),吞吐扩展走多进程(方案 A/B)
|
- 单进程内 OCC 串行是正确性要求(OCC 非线程安全),吞吐扩展走多进程(方案 A/B)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
| 阶段 | 动作 | 状态 |
|
| 阶段 | 动作 | 状态 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 短期 | 方案 A:`--concurrency` 伸缩 + `--max-tasks-per-child` 兜底回收;`cancel_futures=True` 修复重建并发风险 | ✅ 部署参数 2026-09-18 落地(`CELERY_CONCURRENCY` / `CELERY_MAX_TASKS_PER_CHILD` 进 Dockerfile.celery + compose + .env.example) |
|
| 短期 | 方案 A:`--concurrency` 伸缩 + `--max-tasks-per-child` 兜底回收;`cancel_futures=True` 修复重建并发风险 | ✅ 部署参数 2026-09-18 落地(`CELERY_CONCURRENCY` / `CELERY_MAX_TASKS_PER_CHILD` 进 compose + .env.example;2026-09-24 起 worker 与后端共用 `gemold-backend` 镜像、Dockerfile.celery 移除,参数以 compose `command:` 覆盖传递) |
|
||||||
| 中期 | 方案 B:`run_occ(op_name, payload)` 接口演进 + 常驻进程池,kill-on-timeout 根治泄漏 | ✅ 2026-09-18 实施完成(见 §5;回归测试 [tests/test_occ_process_pool.py](../../../tests/test_occ_process_pool.py)) |
|
| 中期 | 方案 B:`run_occ(op_name, payload)` 接口演进 + 常驻进程池,kill-on-timeout 根治泄漏 | ✅ 2026-09-18 实施完成(见 §5;回归测试 [tests/test_occ_process_pool.py](../../../tests/test_occ_process_pool.py)) |
|
||||||
| 长期 | 方案 C:sidecar,仅在出现独立伸缩需求时启动 | 暂不启动 |
|
| 长期 | 方案 C:sidecar,仅在出现独立伸缩需求时启动 | 暂不启动 |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user