Я работаю над проектом, использующим асинхронную библиотеку ccxt
, которая требует, чтобы все ресурсы, используемые определенным классом, были освобождены с явным вызовом сопрограммы класса .close()
.Я хочу выйти из программы с ctrl+c
и дождаться закрытия сопрограммы в исключении.Однако этого никогда не ожидается.
Приложение состоит из модулей harvesters
, strategies
, traders
, broker
и main
(плюс config и тому подобное).Брокер инициирует стратегии, указанные для обмена, и выполняет их.Стратегия инициирует связанный харвестер, который собирает необходимые данные.Он также анализирует данные и порождает трейдера, когда есть выгодная возможность.Основной модуль создает брокера для каждой биржи и запускает его.Я пытался поймать исключение на каждом из этих уровней, но близкая рутина никогда не ожидалась.Я бы предпочел перехватить его в главном модуле, чтобы закрыть все экземпляры обмена.
Харвестер
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)
Main
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()
, но я все еще получаю сообщение об ошибке из библиотеки, которое я должен явно вызвать.Где я могу поймать исключение, чтобы все экземпляры обмена были закрыты должным образом?