实现多进程 epanet 模拟,不保留临时文件

This commit is contained in:
2026-03-18 16:56:44 +08:00
parent c5d3075ae2
commit 7c44654195
6 changed files with 114 additions and 127 deletions
+6 -33
View File
@@ -9,7 +9,6 @@ from fastapi.responses import PlainTextResponse
import app.infra.db.influxdb.api as influxdb_api
import app.services.simulation as simulation
import app.services.globals as globals
from app.infra.cache.redis_client import redis_client
from app.services.tjnetwork import (
run_project,
run_project_return_dict,
@@ -139,36 +138,23 @@ def run_simulation_manually_by_date(
# 必须用这个PlainTextResponse,不然每个key都有引号
@router.get("/runproject/", response_class=PlainTextResponse, summary="运行项目模拟", description="基于指定的管网项目运行标准水力模拟,返回纯文本格式的模拟报告。使用分布式锁机制确保同时只有一个模拟任务运行。")
@router.get("/runproject/", response_class=PlainTextResponse, summary="运行项目模拟", description="基于指定的管网项目运行标准水力模拟,返回纯文本格式的模拟报告。")
async def run_project_endpoint(network: str = Query(..., description="管网名称(或数据库名称)")) -> str:
"""
运行项目模拟
- **network**: 管网名称(或数据库名称)
使用分布式锁机制确保同一时间只有一个模拟任务在运行。如果已有任务在运行,返回409状态码
运行指定管网项目的标准水力模拟并返回文本报告
"""
lock_key = "exclusive_api_lock"
timeout = 120 # 锁自动过期时间(秒)
# 尝试获取锁(NX=True: 不存在时设置,EX=timeout: 过期时间)
acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout)
if not acquired:
raise HTTPException(status_code=409, detail="is in simulation")
else:
try:
return run_project(network)
finally:
# 手动释放锁(可选,依赖过期时间自动释放更安全)
redis_client.delete(lock_key)
return run_project(network)
# DingZQ, 2025-02-04, 返回dict[str, Any]
# output 和 report
# output 是 json
# report 是 text
@router.get("/runprojectreturndict/", summary="运行项目模拟(返回字典)", description="基于指定的管网项目运行标准水力模拟,返回JSON格式的字典,包含输出数据和报告文本。使用分布式锁机制确保同时只有一个模拟任务运行。")
@router.get("/runprojectreturndict/", summary="运行项目模拟(返回字典)", description="基于指定的管网项目运行标准水力模拟,返回JSON格式的字典,包含输出数据和报告文本。")
async def run_project_return_dict_endpoint(network: str = Query(..., description="管网名称(或数据库名称)")) -> dict[str, Any]:
"""
运行项目模拟(返回字典)
@@ -179,22 +165,9 @@ async def run_project_return_dict_endpoint(network: str = Query(..., description
- output: JSON格式的模拟输出数据
- report: 文本格式的模拟报告
使用分布式锁机制确保同一时间只有一个模拟任务在运行
运行指定管网项目的标准水力模拟并返回字典结果
"""
lock_key = "exclusive_api_lock"
timeout = 120 # 锁自动过期时间(秒)
# 尝试获取锁(NX=True: 不存在时设置,EX=timeout: 过期时间)
acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout)
if not acquired:
raise HTTPException(status_code=409, detail="is in simulation")
else:
try:
return run_project_return_dict(network)
finally:
# 手动释放锁(可选,依赖过期时间自动释放更安全)
redis_client.delete(lock_key)
return run_project_return_dict(network)
# put in inp folder, name without extension