python - 在此异步设置中,我在哪里捕获 KeyboardInterrupt 异常
问题描述
我正在开发一个使用ccxt
异步库的项目,该库需要通过显式调用该类的协程来释放某个类使用的所有资源.close()
。我想退出程序ctrl+c
并等待异常中的关闭协程。然而,它永远不会被期待。
该应用程序由模块harvesters
、、、、strategies
和traders
(加上配置等)broker
组成。main
经纪人启动为交易所指定的策略并执行它们。该策略启动相关的收集器,收集必要的数据。它还分析数据并在有获利机会时催生交易者。主模块为每个交易所创建一个代理并运行它。我试图在每个级别捕获异常,但从不等待关闭例程。我宁愿在主模块中捕获它以关闭所有交换实例。
收割机
async def harvest(self):
if not self.routes:
self.routes = await self.get_routes()
for route in self.routes:
self.logger.info("Harvesting route {}".format(route))
await asyncio.sleep(self.exchange.rateLimit / 1000)
yield await self.harvest_route(route)
战略
async def execute(self):
async for route_dct in self.harvester.harvest():
self.logger.debug("Route dictionary: {}".format(route_dct))
await self.try_route(route_dct)
经纪人
async def run(self):
for strategy in self.strategies:
self.strategies[strategy] = getattr(
strategies, strategy)(self.share, self.exchange, self.currency)
while True:
try:
await self.execute_strategies()
except KeyboardInterrupt:
await safe_exit(self.exchange)
主要的
async def main():
await load_exchanges()
await load_markets()
brokers = [Broker(
share,
exchanges[id]["api"],
currency,
exchanges[id]["strategies"]
) for id in exchanges]
futures = [broker.run() for broker in brokers]
for future in asyncio.as_completed(futures):
executed = await future
return executed
if __name__ == "__main__":
status = asyncio.run(main())
sys.exit(status)
我曾预计close()
协程会被等待,但我仍然从库中收到一个错误,我必须明确调用它。我在哪里捕获异常以便正确关闭所有交换实例?
解决方案
Somewhere in your code should be entry point, where event loop is started.
Usually it is one of functions below:
loop.run_until_complete(main())
loop.run_forever()
asyncio.run(main())
When ctrl+C
happens KeyboardInterrupt
can be catched at this line. When it happened to execute some finalizing coroutine you can run event loop again.
This little example shows idea:
import asyncio
async def main():
print('Started, press ctrl+C')
await asyncio.sleep(10)
async def close():
print('Finalazing...')
await asyncio.sleep(1)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
except KeyboardInterrupt:
loop.run_until_complete(close())
finally:
print('Program finished')
推荐阅读
- excel - Excel - 如何在数据透视表中查找数据并使用下一个单元格中的值?
- postgresql - PostgreSQL 用户密码重置
- python - 为什么 SeparableConv2D 比 Conv2D 慢?
- ansible - 使用另一个 dict var 创建 var
- python - 使用 selenium 的 Web 驱动程序获取冠状病毒数据的问题
- python - 安装像 pygal 这样的模块,以便它们在 Spyder 中工作
- node.js - 无法使用 azure 函数更新许多值 - nodejs
- android - BUILD FAILED in 18s Finished with error: Gradle task assembleDebug failed with exit code 1
- reactjs - 为什么引导按钮组件中的链接不起作用?
- neo4j - 在 Where 子句中引入的 Neo4j 索引