feat: P1 补齐(自动评审队列、自动化+分诊、并发 caps、运行时审批队列)

This commit is contained in:
host committed 2026-10-27 15:53:50 +08:00
1 parent 29efc6c61f
commit e0cecd70aa
18 files changed
+3474 -27

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
"""Worker 并发上限:配置解析与认领判断(纯函数,无 DB、无 IO)。
配置来源与优先级(高到低):
1. 显式值:Worker 构造参数 capacity / CLI --worker-capacity。
2. 环境变量 CLOUD_WORKER_CAPACITY(CLI 未给时生效)。
3. 默认值 1:默认行为不得弱于现状,即旧串行行为。
非法值(非整数、<= 0)一律归一化为 1,绝不出现 0 上限导致
worker 永远认领不到任务,也绝不出现负数上限。
workers 表的 capacity 是注册表展示值,不是控制面下推:
本地 worker 只执行自己启动时的配置,表里被改大的值不会
悄悄抬高本 worker 的上限(否则 stale 行或误写会放大并发)。
上限口径(单 worker 本地计数):
- running 数 = Worker._running 的条目数(_running_lock 下读)。
- 启动中的任务也算:_claim 占位时就先在 _running 里建空条目,
执行器起 proc / 容器后 _running_set 只往该条目里补字段,
不新增条目;所以“已认领未起进程”与“已起进程”都占一个槽。
- 同一任务重复占位不重复计数(dict 按 task_id 去重)。
- 本模块只管单 worker 上限;多 worker 全局上限不在此列,
见汇报里的诚实边界(项目级上限同样是遗留项)。
"""
import os
DEFAULT_CAPACITY = 1
ENV_VAR = "CLOUD_WORKER_CAPACITY"
def parse_capacity(value):
"""把任意输入归一化为 >= 1 的整数上限;非法值返回 1。"""
try:
capacity = int(value)
except (TypeError, ValueError):
return DEFAULT_CAPACITY
if capacity < 1:
return DEFAULT_CAPACITY
return capacity
def resolve_capacity(explicit=None, env=None):
"""按“显式 > 环境变量 > 默认 1”解析上限。
explicit 为 None 表示调用方未给(CLI 未传 --worker-capacity
时 argparse 默认即 None);env 默认读进程环境,单测可注入
普通 dict。显式值即使非法也按非法处理(归一为 1),不回落
到环境变量:显式给错了就该按 1 跑,而不是悄悄用环境值。
"""
if explicit is not None:
return parse_capacity(explicit)
source = env if env is not None else os.environ
try:
raw = source.get(ENV_VAR)
except Exception:
raw = None
if raw is None or (isinstance(raw, str) and not raw.strip()):
return DEFAULT_CAPACITY
return parse_capacity(raw)
def effective_capacity(capacity):
"""运行期上限:构造后 self.capacity 可能来自旧调用方,统一归一。"""
return parse_capacity(capacity)
def running_count(running_snapshot):
"""_running 快照的条目数:空条目(启动中)同样计数。"""
try:
return len(running_snapshot)
except TypeError:
return 0
def can_claim(running_count_value, capacity):
"""未满返回 True;running 数达到上限时不再认领。"""
return running_count_value < effective_capacity(capacity)