The need to close the asyncio event loop explicitly

Story:

I am currently looking at basic examples of asyncio , specifically this one is the easiest HTTP client possible. The main function starts the event loop, is executed until the data sampling is completed and the event loop is completed:

def main(): loop = get_event_loop() try: body = loop.run_until_complete(fetch()) finally: loop.close() print(body.decode('latin-1'), end='') 

But, the code also works if I omit loop.close() :

 def main(): loop = get_event_loop() body = loop.run_until_complete(fetch()) print(body.decode('latin-1'), end='') 

Question:

While there is an example, the question is general - what could potentially go wrong if you forget to close the asyncio event loop? Is an event loop always an implicit closure?

+8
source share
1 answer

.close() can be used by various implementations of the event loop to free up system resources allocated by the loop (or do something else). If you look at the _UnixSelectorEventLoop code, which is the (default) IOLoop used on Linux, you will find the following code:

 def close(self): super().close() for sig in list(self._signal_handlers): self.remove_signal_handler(sig) 

Here, for example, close() removes the signal handlers registered with loop.add_signal_handler() .

Since several IOLoops can be run on different threads, or new IOLoops can be created after closing the old one (see asyncio.new_event_loop() ), closing them should be considered a good habit.

Refresh

Starting with Python 3.7, it is recommended to use asyncio.run instead of run_until_complete() :

 # Python 3.7+ def main(): body = asyncio.run(fetch()) print(body.decode('latin-1'), end='') 

Among other things, asyncio.run will take care of the finally close() loop.

+5
source

Source: https://habr.com/ru/post/1013311/


All Articles