我正在使用 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
在后台播种,任务实际上正在运行?