refactor: unify protected task completion

This commit is contained in:
jxxghp
2026-08-24 03:20:45 +08:00
parent 10582277e2
commit 22848eeda2
7 changed files with 64 additions and 34 deletions
+2 -8
View File
@@ -45,6 +45,7 @@ from app.adapters.system.plugin.manifest import (
from app.runtime.log import logger
from app.runtime.observability import observe_compat_facade
from app.runtime.execution import (
await_task_to_terminal,
run_in_threadpool_to_completion as _await_thread_operation,
)
from app.runtime.tasks import get_task_registry
@@ -1499,15 +1500,8 @@ class PluginHelper(metaclass=WeakSingleton):
await asyncio.to_thread(created_file.unlink, missing_ok=True)
cleanup_task = asyncio.create_task(cleanup_created_file())
while not cleanup_task.done():
try:
await asyncio.shield(cleanup_task)
except asyncio.CancelledError:
continue
except Exception:
break
try:
await cleanup_task
await await_task_to_terminal(cleanup_task)
except Exception as err:
logger.warning(f"[UV] 取消后清理运行环境约束文件失败:{err}")
raise
+4 -19
View File
@@ -9,6 +9,7 @@ from typing import Any, ContextManager, Optional
from app.schemas.exception import PersistenceUnavailableError
from app.application.plugin.lifecycle import plugin_lifecycle
from app.runtime.execution import await_task_to_terminal
from app.runtime.log import logger
from app.schemas.exception import PluginMutationRejectedError
@@ -29,17 +30,6 @@ PluginRegistrationRefresher = Callable[[str], Awaitable[object]]
PluginMutationAdmission = Callable[[str], ContextManager[None]]
PluginPackageWriteGuard = Callable[[str], ContextManager[None]]
async def _await_task_to_terminal(task: asyncio.Task[Any]) -> Any:
"""忽略调用方的重复取消,直到受保护子任务进入真实终态。"""
while not task.done():
try:
return await asyncio.shield(task)
except asyncio.CancelledError:
continue
return task.result()
@dataclass(frozen=True, slots=True)
class PluginInstallRollback:
"""描述失败安装中各类可补偿副作用的恢复结果。"""
@@ -193,7 +183,7 @@ class PluginInstallCommand:
state.checkpoint = checkpoint
except asyncio.CancelledError:
try:
state.checkpoint = await _await_task_to_terminal(checkpoint_task)
state.checkpoint = await await_task_to_terminal(checkpoint_task)
except BaseException:
pass
raise
@@ -369,7 +359,7 @@ class PluginInstallCommand:
)
)
try:
result = await _await_task_to_terminal(rollback_task)
result = await await_task_to_terminal(rollback_task)
except BaseException as err:
logger.error(f"插件 {plugin_id} 取消后的补偿失败:{err}")
return
@@ -410,12 +400,7 @@ class PluginInstallCommand:
cleanup_task = asyncio.create_task(
self._restore_refreshed_runtime(plugin_id)
)
while not cleanup_task.done():
try:
await asyncio.shield(cleanup_task)
except asyncio.CancelledError:
continue
rollback = await cleanup_task
rollback = await await_task_to_terminal(cleanup_task)
state.refresh_compensated = True
if rollback.errors:
logger.error(
+18 -1
View File
@@ -3,12 +3,29 @@ import inspect
import time
from contextvars import copy_context
from functools import partial, wraps
from typing import Any, Callable
from typing import Any, Callable, TypeVar
from app.schemas.exception import ImmediateException
from anyio.to_thread import run_sync
TaskResult = TypeVar("TaskResult")
async def await_task_to_terminal(
task: asyncio.Future[TaskResult],
) -> TaskResult:
"""忽略当前调用方的重复取消,直到受保护任务进入真实终态。"""
while not task.done():
try:
await asyncio.shield(task)
except asyncio.CancelledError:
continue
except BaseException:
break
return task.result()
async def run_in_threadpool(
func: Callable[..., Any],
*args: Any,