코딩관계론

telegram.error.NetworkErrorAsyncIO Event Loop Closed 오류 본문

TroubleShooting

telegram.error.NetworkErrorAsyncIO Event Loop Closed 오류

개발자_티모 2023. 8. 12. 21:30
반응형

개요

Telegram 라이브러리 사용 과정에서 "telegram.error.NetworkError: Unknown error in HTTP implementation: RuntimeError('Event loop is closed')" 오류가 발생했습니다. 이 글에서는 해당 오류의 발생 원인을 분석하고 해결 방법을 제시합니다.


환경

  • 우분투 
  • Python 버전: 3.8

오류 해결 시도

이 문제를 해결하기 위해 다음과 같은 접근을 시도했습니다. 오류의 발생과정과 관련 코드를 분석해보니 asyncio.run()을 이용하여 메세지 전송을 시도하는 부분에서 오류가 발생했습니다. 단 send_message 함수를 한번 호출하는 것은 괜찮았지만, 두 번 이상 호출하는 경우 해결하려는 오류를 만날 수 있었습니다.

def send_message(self, msg, chat_id):
    asyncio.run(self.__send_telegram_message(msg=msg, chat_id=chat_id))

 

하지만 "Event loop is closed" 오류는 주로 비동기 프로그래밍 환경에서 나타나며, 주로 asyncio와 같은 비동기 라이브러리를 사용하는 상황에서 발생합니다. 이 오류는 이벤트 루프(event loop)가 이미 닫혔음에도 불구하고 다시 사용하려고 할 때 발생합니다.

 

그러나 위의 코드에서는 asyncio.run() 함수의 동작 방식을 확인해보면, 매번 새로운 이벤트 루프를 생성하고 사용한 뒤 종료합니다. 자세한 내용은 여기에서 확인할 수 있습니다. 

 

따라서, 위의 에러는 asyncio에 의해 발생한 오류보다는, 오히려 텔레그램 오픈 소스의 버그에 기인한 것으로 추측됩니다.

이 문제를 해결하기 위해 단일 이벤트 루프를 생성하여 관리하는 방식으로 변경했습니다. 아래와 같이 클래스 내에서 이벤트 루프를 생성하고 이를 활용하는 방식입니다.

    def send_message(self, msg, chat_id=""):
        self.loop.run_until_complete(self.__send_telegram_message(msg=msg, chat_id=chat_id))
        
    def close(self):
        self.loop.close()

 

그러나 위 방법도 좋은 방법은 아닙니다. python docs를 참고하면 'run_until_complete'보다는 'asyncio.run'을 사용해라라고 되어있기 때문입니다.

 

참고자료

https://stackoverflow.com/questions/69035759/using-asyncio-run-is-it-safe-to-run-multiple-times

 

Using asyncio.run, is it safe to run multiple times?

The documentation for asyncio.run states: This function always creates a new event loop and closes it at the end. It should be used as a main entry point for asyncio programs, and should ideally o...

stackoverflow.com

https://docs.python.org/3.9/library/asyncio-task.html#asyncio.run

 

Coroutines and Tasks — Python 3.9.17 documentation

Coroutines and Tasks This section outlines high-level asyncio APIs to work with coroutines and Tasks. Coroutines declared with the async/await syntax is the preferred way of writing asyncio applications. For example, the following snippet of code prints

docs.python.org

 

반응형