hotfix: autoscaler queue_depth NULL depends_on blinded scaler
queue_depth turned a NULL depends_on into [None], and ready_tasks then required None to be in completed_ids, so such tasks never counted as ready. Worker pick_next was unaffected (_task_from_row maps NULL to []), which is why tasks still ran while the scaler always saw depth 0 and never scaled up (proven live: depth probe with 1 queued task returned 0). NULL now means no dependencies, with a regression test.
This commit is contained in:
1 parent
951730e224
commit
b74deffb26
2 files changed
+27
-1
No files matched your search
+9
-1
@@ -65,7 +65,15 @@ def queue_depth(db_path, executor=None):
|
||||
deps = row["depends_on"]
|
||||
except (KeyError, IndexError, TypeError):
|
||||
deps = []
|
||||
if isinstance(deps, str):
|
||||
if deps is None:
|
||||
# depends_on 为 NULL(裸 SQL 插的任务、或老数据)表示
|
||||
# 无依赖,绝不能变成 [None]——那样 ready_tasks 会判定
|
||||
# 它依赖一个永远不存在的 None,任务永远不算就绪,
|
||||
# scaler 也就永远看不到深度(2026-10-26 实测教训:
|
||||
# worker 的 _task_from_row 对 NULL 处理正确所以能
|
||||
# 正常认领,只有 scaler 的深度计算被这个 bug 致盲)。
|
||||
deps = []
|
||||
elif isinstance(deps, str):
|
||||
try:
|
||||
deps = json.loads(deps) if deps else []
|
||||
except ValueError:
|
||||
|
||||
@@ -85,6 +85,24 @@ class QueueDepthTestCase(unittest.TestCase):
|
||||
_set_status(self.db_path, "A", "completed")
|
||||
self.assertEqual(queue_depth(self.db_path), 1)
|
||||
|
||||
def test_null_depends_on_counts_as_ready(self):
|
||||
# 回归:depends_on 为 NULL 时必须算无依赖,不能变成
|
||||
# [None] 导致任务永远不算就绪(scaler 致盲)。
|
||||
conn = sqlite3.connect(self.db_path)
|
||||
try:
|
||||
now = time.time()
|
||||
conn.execute(
|
||||
"INSERT INTO tasks(id, project_id, prompt, status,"
|
||||
" idempotency_key, depends_on, priority, created_by,"
|
||||
" created_at, updated_at, last_heartbeat)"
|
||||
" VALUES('N', 'p1', 'x', 'queued', NULL, NULL, 0,"
|
||||
" 'tester', ?, ?, NULL)",
|
||||
(now, now))
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
self.assertEqual(queue_depth(self.db_path), 1)
|
||||
|
||||
def test_dependency_cycle_counts_zero(self):
|
||||
_insert_task(self.db_path, "A", depends_on='["B"]')
|
||||
_insert_task(self.db_path, "B", depends_on='["A"]')
|
||||
|
||||
Reference in new issue
Block a user