mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 07:27:15 +08:00
fix(plugin): make installation lifecycle cancellable
This commit is contained in:
@@ -364,5 +364,17 @@ class PluginDependencyInstaller:
|
||||
return await asyncio.to_thread(self.find_missing)
|
||||
|
||||
async def async_install(self, dependencies: list[str]) -> tuple[bool, str]:
|
||||
"""在线程池中安装依赖,复用同步包安装策略。"""
|
||||
return await asyncio.to_thread(self.install, dependencies)
|
||||
"""异步安装依赖,使用可取消的包安装子进程。"""
|
||||
if not dependencies:
|
||||
return False, "没有传入需要安装的依赖项"
|
||||
try:
|
||||
manifest_paths = [manifest.path for manifest in self._plugin_manifests()]
|
||||
if not manifest_paths:
|
||||
return False, "没有找到已安装插件的依赖清单"
|
||||
return await self._helper.async_install_packages_with_fallback(
|
||||
manifest_paths,
|
||||
self._wheels_dirs(),
|
||||
)
|
||||
except Exception as err:
|
||||
logger.error(f"安装依赖项时发生错误:{err}")
|
||||
return False, f"安装依赖项时发生错误:{err}"
|
||||
|
||||
@@ -19,6 +19,19 @@ from app.runtime.settings import RuntimeSettingsCompat
|
||||
settings = RuntimeSettingsCompat()
|
||||
|
||||
|
||||
async def _await_thread_operation(func, *args, **kwargs):
|
||||
"""取消请求到达时先等待文件操作收口,避免后台线程继续写运行目录。"""
|
||||
task = asyncio.create_task(asyncio.to_thread(func, *args, **kwargs))
|
||||
try:
|
||||
return await asyncio.shield(task)
|
||||
except asyncio.CancelledError:
|
||||
try:
|
||||
await asyncio.shield(task)
|
||||
except BaseException:
|
||||
pass
|
||||
raise
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class PluginPackageCheckpoint:
|
||||
"""记录一次插件包变更前可用于补偿恢复的文件快照。"""
|
||||
@@ -74,7 +87,7 @@ class PluginPackageManager:
|
||||
|
||||
async def async_checkpoint(self, plugin_id: str) -> PluginPackageCheckpoint:
|
||||
"""在线程池中创建插件包文件快照。"""
|
||||
return await asyncio.to_thread(self.checkpoint, plugin_id)
|
||||
return await _await_thread_operation(self.checkpoint, plugin_id)
|
||||
|
||||
@staticmethod
|
||||
def commit(checkpoint: PluginPackageCheckpoint) -> None:
|
||||
@@ -83,7 +96,7 @@ class PluginPackageManager:
|
||||
|
||||
async def async_commit(self, checkpoint: PluginPackageCheckpoint) -> None:
|
||||
"""在线程池中清理已提交的插件包快照。"""
|
||||
await asyncio.to_thread(self.commit, checkpoint)
|
||||
await _await_thread_operation(self.commit, checkpoint)
|
||||
|
||||
@staticmethod
|
||||
def rollback(checkpoint: PluginPackageCheckpoint) -> None:
|
||||
@@ -101,7 +114,7 @@ class PluginPackageManager:
|
||||
|
||||
async def async_rollback(self, checkpoint: PluginPackageCheckpoint) -> None:
|
||||
"""在线程池中恢复插件包文件快照。"""
|
||||
await asyncio.to_thread(self.rollback, checkpoint)
|
||||
await _await_thread_operation(self.rollback, checkpoint)
|
||||
|
||||
def install(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user