0

我正在使用 aioaria2 websocket 客户端,如果下载开始或完成,它可以使用该功能作为通知。基于代码创建了处理通知的函数,asyncio.create_task并且它在后台永远循环。我需要种子文件,因为 aioaria2 还没有提供所以我正在使用asyncio.create_subprocess_exec,因为我不需要种子文件函数的返回值,我开始工作,asyncio.create_task它应该可以节省我大量的时间而无需等待那份工作。

    async def seedFile(self, file: util.aria2.Download) -> None:
        file_path = Path(str(file.dir / file.info_hash) + ".torrent")
        if not file_path.is_file():
            return

        self.log.info(f"Seeding: [gid: '{file.gid}']")
        port = util.aria2.get_free_port()
        cmd = [
            "aria2c", "--enable-rpc", "--rpc-listen-all=false",
            f"--rpc-listen-port={port}", "--bt-seed-unverified=true",
            "--seed-ratio=1", f"-i {str(file_path)}"
        ]

        try:
            _, stderr, ret = await util.system.run_command(*cmd)
        except Exception as e:  # skipcq: PYL-W0703
            self.log.warning(e)
            return

        if ret != 0:
            self.log.info("Seeding: [gid: '{file.gid}'] - Failed")
            self.log.warning(stderr)
            return

        self.log.info(f"Seeding: [gid: '{file.gid}'] - Complete")

但是一旦它在await util.system.run_command任务上总是挂起并且永远不会运行,如果我等待另一个工作它会像死锁一样卡住,但任务甚至没有运行。那是因为 create_subprocess_exec 不能在后台运行吗?

aioaria2通知代码

    async def listen(self) -> None:
        try:
            while not self.closed:
                try:
                    data = await self.client_session.receive_json(loads=self.loads)
                except TypeError:  # aria2抽了
                    continue
                if not data or not isinstance(data, dict):
                    continue
                asyncio.create_task(self.handle_event(data))
        finally:
            await self.close()

句柄事件

    async def handle_event(self, data: dict) -> None:
        if "result" in data or "error" in data:
            ResultStore.add_result(data)
            # if "result" in self.functions:
            #     await asyncio.gather(*map(lambda x: x(self, future), self.functions["result"]))
        if "method" in data:
            method = data["method"]
            if method in self.functions:  # TODO 有鬼
                await asyncio.gather(*map(lambda x: x(self, data), self.functions[method]))

我下载完成后的seedFile函数

    async def onDownloadComplete(self, client: Aria2WebsocketClient,
                                 data: Union[Dict[str, Any], Any]) -> None:
        gid = data["params"][0]["gid"]
        file = await self.getDownload(client, gid)
        if file.bittorrent:
            self.loop.create_task(self.seedFile(file), name=f"Seed-{file.gid}")

我无法在下载时播种(默认行为 aria2),因为下载完成后会导致一些不好的问题,因为文件状态在种子完成之前仍然处于活动状态,所以我的工作是在下载时不播种,然后在后台下载完成后播种asyncio.create_subprocess_exec但正如我在开始时所说的那样,任务总是悬而未决,无论如何,无论我多么等待它。await, asyncio.wait, asyncio.wait_for,asyncio.gather都一样使调用者死锁或永远循环

问题 我如何asyncio.create_subprocess_exec在后台播种,任务实际上正在运行?

4

0 回答 0