fix(automation): 待重登积压数不再被批次上限截断

页面上「待重登候选」显示 10 —— 那只是 ck_relogin 的 batch_size,不是真实积压。
根因是我用作业的候选查询取 count,而那个查询带 LIMIT batch_size,count 自然
被截断在批次上限;线上实际有一千多条待重登,页面却恒显示 10。

改为独立的 count_pending_relogin():同一套资格条件(invalid + 有 CK + 允许自动
管理 + 未转人工 + 未超每日上限),但不带 LIMIT,也不按退避窗口过滤 —— 退避是
「什么时候试」的细节,不影响「还有多少要处理」。

新增测试:批次上限为 10 时,25 条积压必须报 25。

另:本次一并还原了 ck_health.py 里被外部改动引入的回归 —— 有人把选行排序改成
text("login_tasks.ck_checked_at ASC NULLS FIRST"),那是逐字透传给数据库的片段,
而 MySQL 不支持 NULLS FIRST(今天线上就是这么炸的 1064)。已恢复成可移植写法,
test_generated_sql_is_mysql_compatible 会拦住这类改动(本次正是它先报的红)。

全量 298 通过。
This commit is contained in:
yml2213
2026-10-02 21:05:18 +08:00
parent ed6e186655
commit 2c532df14f
3 changed files with 45 additions and 14 deletions
@@ -114,6 +114,30 @@ def build_select_query(
).limit(max(int(job.batch_size or 0), 1))
def count_pending_relogin(db: Session, *, max_attempts: int = 2) -> int:
"""待自动重登的**积压**条数(给页面显示用)。
刻意不复用 ``build_select_query``:那个查询带 ``LIMIT batch_size``,用它取
count 只会得到批次上限(页面上显示恒等于 10),完全看不出积压。这里也**不
按退避窗口过滤** —— 退避是「什么时候试」的细节,不影响「还有多少要处理」。
"""
return int(
db.query(func.count(LoginTask.id))
.join(Account, LoginTask.account_id == Account.id)
.filter(LoginTask.ck_check_status == "invalid")
.filter(cookie_holding_filter())
.filter(Account.auto_managed.is_(True))
.filter(LoginTask.relogin_attempts < max_attempts)
.filter(
func.coalesce(LoginTask.relogin_failure_kind, "").notin_(
tuple(MANUAL_KINDS)
)
)
.scalar()
or 0
)
def _system_user_id(db: Session) -> int | None:
"""自动重登要用一个真实用户身份落 ``created_by``(外键非空,且便于追责)。