Я использую сетевую библиотеку, которая предоставляет оболочку для использования функций сопрограммы с asyncio
.Когда я написал тест, который случайным образом закрывает соединение (чтобы проверить, устойчива ли моя программа в плохих условиях), я обнаружил, что оно зависает бесконечно.
Это выглядело как ошибка в оболочке, предоставленной библиотекойиспользуя, потому что программа зависает в ожидании обратного вызова от loop.add_reader()
или loop.add_writer()
, но тогда я не мог найти, как получать уведомления, когда сокет закрыт.
Это минимальная программа, которая показывает, чтопроисходит с моей программой:
import asyncio
import socket
async def kill_later(c):
await asyncio.sleep(0.1)
c.close()
async def main():
loop = asyncio.get_running_loop()
c = socket.create_connection(('www.google.com', 80))
c.setblocking(0)
ev = asyncio.Event()
loop.add_reader(c, ev.set)
# Closes the socket after 0.1 ms:
asyncio.create_task(kill_later(c))
print("waiting...")
#### ↓ THIS WAITS FOREVER ↓ ####
await ev.wait()
asyncio.run(main())
Мой вопрос: как получить уведомление о закрытии сокета с помощью цикла asyncio
?
РЕДАКТИРОВАТЬ: из-за широкого спроса, сделал сокет не-блокирование, но это не имеет значения, потому что add_reader()
не пытается выполнить какой-либо ввод-вывод на сокете, просто следит за тем, когда он будет готов.