Files
geMoldInsight/src/moldinsight/api/core_modules.py
T
cjw e728dcd226 批次4后续专项完成:D11清偿 + OCC方案B实施 + 部署参数 + D2诚实标注 + CI门禁
① D11 HTML 报告 RustFS 单源化(TECH_DEBT P2 清偿):可视化产物写任务临时目录后
   裸传报告键 html/reports/{filename}(文件名寻址),/html StaticFiles 挂载删除,
   新增 html_report_router 根路径代理(报告键→遗留 JSON 包装→本地卷兜底→404,
   防穿越);URL 形状 /html/{filename} 不变,持久化引用零迁移;celery 摘除
   html_data 卷,镜像不再烤入陈旧报告;顺带删除 get_stp_file_with_data 死数据块
② OCC 方案 B(D10 清偿):run_occ(op_name, payload) 契约 + 常驻工作进程池
   (occ_process_pool + occ_worker 操作注册表),超时/崩溃 terminate 换新补位、
   任务级超时 recover 整体重建,残留线程泄漏根治;TopoDS 不跨进程(generate_cavity
   分模 + 方案 STEP 持久化全在子进程内,返回 export_manifest);删除内存形状缓存链、
   CADExporter.export_mold_results、shape_loader(→ stp_materializer)
③ OCC 方案 A 部署参数:CELERY_CONCURRENCY / CELERY_MAX_TASKS_PER_CHILD 进
   Dockerfile.celery + compose + .env.example
④ D2 诚实标注:铝价响应带 source: "simulated",前端按来源渲染标注(原硬编码
   "上海期货交易所"属虚假声明),死代码 getAluminumPrice 删除
⑤ CI 门禁:.gitea/workflows/ci.yml 三 job(pytest / 前端构建含 vue-tsc /
   openapi 漂移检测)

接口变更三件套随批完成(openapi 76→77 paths + gen:api + 前端构建通过;方案 B
接口面零变化)。测试基线 143 passed, 0 skipped(新增 16 项)。文档六处同步。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-18 17:22:01 +08:00

49 lines
2.1 KiB
Python
Raw 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.
"""核心计算模块的惰性装载器(原 advanced_router._get_cached_import,D1 拆分时上提共用)。
- 惰性导入:避免路由模块级加载核心包(含 OCC 重模块)的导入开销与循环依赖
- 装载失败返回 None 且不缓存失败(与原实现一致,端点统一 503「服务不可用」)
- 实例缓存:设计/加工模块为纯 Python 计算(构造后无 self 突变,方法仅读入参),
可安全地被 asyncio.to_thread 并发调用;OCC 相关的 side_action_designer
经 processing_service.run_occ 的常驻 OCC 进程池使用(方案 B,见
docs/topics/performance/OCC_THROUGHPUT.md)
"""
import threading
from typing import Optional
from shared.utils.logger import get_logger
logger = get_logger(__name__)
_lock = threading.Lock()
_instances: dict = {}
_LOADERS = {
"side_action_designer": ("moldinsight.core.side_action_designer", "SideActionDesigner"),
"cavity_layout_optimizer": ("moldinsight.core.cavity_layout_optimizer", "CavityLayoutOptimizer"),
"mold_system_designer": ("moldinsight.core.mold_system_designer", "MoldSystemDesigner"),
"mold_cam_designer": ("moldinsight.core.mold_cam", "MoldCAMDesigner"),
"collision_detector": ("moldinsight.core.mold_machining", "CollisionDetector"),
"toolpath_optimizer": ("moldinsight.core.mold_machining", "ToolpathOptimizer"),
"edm_designer": ("moldinsight.core.mold_machining", "EDMElectrodeDesigner"),
"machining_simulator": ("moldinsight.core.mold_machining", "MachiningSimulator"),
}
def get_core_module(key: str):
if key in _instances:
return _instances[key]
if key not in _LOADERS:
return None
with _lock:
if key in _instances:
return _instances[key]
module_path, class_name = _LOADERS[key]
try:
module = __import__(module_path, fromlist=[class_name])
instance = getattr(module, class_name)()
except Exception as e:
logger.warning(f"核心模块 {key} 加载失败: {e}")
return None
_instances[key] = instance
return instance