This commit is contained in:
Neo
2026-03-15 10:15:02 +08:00
parent 2dd217522c
commit 72bb11b34f
916 changed files with 65306 additions and 16102803 deletions

View File

@@ -314,22 +314,55 @@ class TaskExecutor:
async def cancel(self, execution_id: str) -> bool:
"""向子进程发送终止信号。
如果进程仍在内存中,发送 terminate 信号;
如果进程已不在内存中(如后端重启后),但数据库中仍为 running
则直接将数据库状态标记为 cancelled幽灵记录兜底
Returns:
True 表示成功发送终止信号False 表示进程不存在或已退出
True 表示成功取消False 表示任务不存在或已完成
"""
proc = self._processes.get(execution_id)
if proc is None:
return False
# subprocess.Popen: poll() 返回 None 表示仍在运行
if proc.poll() is not None:
return False
if proc is not None:
# 进程仍在内存中
if proc.poll() is not None:
return False
logger.info("取消 ETL 子进程 [%s], pid=%s", execution_id, proc.pid)
try:
proc.terminate()
except ProcessLookupError:
return False
return True
logger.info("取消 ETL 子进程 [%s], pid=%s", execution_id, proc.pid)
# 进程不在内存中(后端重启等场景),尝试兜底修正数据库幽灵记录
try:
proc.terminate()
except ProcessLookupError:
return False
return True
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"""
UPDATE task_execution_log
SET status = 'cancelled',
finished_at = NOW(),
error_log = COALESCE(error_log, '')
|| E'\n[cancel 兜底] 进程已不在内存中,标记为 cancelled'
WHERE id = %s AND status = 'running'
""",
(execution_id,),
)
updated = cur.rowcount
conn.commit()
finally:
conn.close()
if updated:
logger.info(
"兜底取消 execution_log [%s]:数据库状态从 running → cancelled",
execution_id,
)
return True
except Exception:
logger.exception("兜底取消 execution_log [%s] 失败", execution_id)
return False
# ------------------------------------------------------------------
# 数据库操作(同步,在线程池中执行也可,此处简单直连)