From 7e8d3a9c491d883ce8aeba25c5aaba24b7c04124 Mon Sep 17 00:00:00 2001 From: ThearchyHelios Date: Fri, 16 Oct 2026 17:46:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=A3=E5=BE=84=E6=AF=94=E5=AF=B9=E7=9A=84?= =?UTF-8?q?=20drain=EF=BC=88=E6=B5=8B=E8=AF=95=E7=94=A8=EF=BC=89=E5=8F=AA?= =?UTF-8?q?=E7=AD=89=E8=BF=98=E6=B2=A1=E5=81=9A=E5=AE=8C=E7=9A=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=EF=BC=8C=E5=81=9A=E5=AE=8C=E8=BF=98=E7=95=99=E5=9C=A8?= =?UTF-8?q?=E7=99=BB=E8=AE=B0=E9=87=8C=E7=9A=84=E9=A1=BA=E6=89=8B=E5=8E=BB?= =?UTF-8?q?=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为什么:并行跑全量测试时偶发过 drain 原地空转(faulthandler 抓到主线程一直在 drain 里,每轮 gather 都立刻返回),四次全量里挂了两次。这一波起整题等价的探索运行比完会接着自动出具,后台任务的进出更密。改成只 gather 没做完的、把做完的从登记里去掉之后,连跑两次全量都没再出现。drain 只给测试用,服务里不调它;没能在单进程里复现出根因,照实记进遗留。 --- backend/app/ledger/match.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/app/ledger/match.py b/backend/app/ledger/match.py index fc2643d9..85804248 100644 --- a/backend/app/ledger/match.py +++ b/backend/app/ledger/match.py @@ -596,9 +596,17 @@ def _mine() -> list[asyncio.Task[Any]]: async def drain() -> None: - """等这个事件循环里的后台比对都做完(测试用)。""" - while tasks := _mine(): - await asyncio.gather(*tasks, return_exceptions=True) + """等这个事件循环里的后台比对都做完(测试用)。只等还没做完的:已经做完、还留在登记里的(完成回调还没来得及跑)顺手 + 去掉——不然对着做完的任务反复 gather,事件循环原地空转(并行跑全量测试时偶发过)。""" + while True: + tasks = _mine() + for task in tasks: + if task.done(): + _background.discard(task) + live = [task for task in tasks if not task.done()] + if not live: + return + await asyncio.gather(*live, return_exceptions=True) async def shutdown() -> None: