main:新增并发控制功能

变更内容:
- 增加 `max_concurrent_jobs` 配置项,支持设置最大并发任务数。
- 为 `JobManager` 添加信号量控制实现任务并发限制。
- 新增获取任务并发状态的接口 `/jobs/concurrency/status`。
- 编写并发控制功能相关的测试用
This commit is contained in:
2026-02-02 17:11:52 +08:00
parent c6f8714c4d
commit 2df59f0f1f
5 changed files with 265 additions and 54 deletions

View File

@@ -152,3 +152,21 @@ class JobStatusResponse(BaseModel):
result: Optional[Dict[str, Any]] = Field(None, description="执行结果(仅完成时返回)")
error: Optional[str] = Field(None, description="错误信息(仅失败时返回)")
metadata: Optional[Dict[str, Any]] = Field(None, description="元数据信息")
class ConcurrencyStatusResponse(BaseModel):
"""并发状态响应"""
model_config = ConfigDict(
json_schema_extra={
"example": {
"max_concurrent": 10,
"available_slots": 7,
"running_jobs": 3,
}
}
)
max_concurrent: int = Field(..., description="最大并发任务数")
available_slots: int = Field(..., description="当前可用槽位数")
running_jobs: int = Field(..., description="当前运行中的任务数")

View File

@@ -15,6 +15,7 @@ from .models import (
JobCreateResponse,
JobStatusResponse,
JobStatus,
ConcurrencyStatusResponse,
)
from .dependencies import get_request_id
from ..algorithms.prime_checker import PrimeChecker
@@ -292,3 +293,57 @@ async def get_job_status(job_id: str):
"message": str(e),
},
)
@router.get(
"/jobs/concurrency/status",
response_model=ConcurrencyStatusResponse,
summary="查询并发状态",
description="查询任务管理器的并发执行状态",
responses={
200: {"description": "成功", "model": ConcurrencyStatusResponse},
503: {"description": "服务不可用", "model": ErrorResponse},
},
)
async def get_concurrency_status():
"""
查询并发状态
返回当前任务管理器的并发执行状态,包括:
- 最大并发任务数
- 当前可用槽位数
- 当前运行中的任务数
"""
try:
job_manager = await get_job_manager()
# 检查任务管理器是否可用
if not job_manager.is_available():
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail={
"error": "SERVICE_UNAVAILABLE",
"message": "任务管理器不可用",
},
)
concurrency_status = job_manager.get_concurrency_status()
return ConcurrencyStatusResponse(
max_concurrent=concurrency_status["max_concurrent"],
available_slots=concurrency_status["available_slots"],
running_jobs=concurrency_status["running_jobs"],
)
except HTTPException:
raise
except Exception as e:
logger.error(f"查询并发状态失败: {str(e)}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={
"error": "INTERNAL_ERROR",
"message": str(e),
},
)