As I understand it : if an asyncio task is waiting on a future and this future is destroyed by the garbage collector then the task is destroyed too. Which is great because the task would never have completed anyway because the future will never have a result.
This behavior makes total sense, I might have in my program futures that are destroyed and I like that the tasks that could be waiting on them will not cause memory leak by sticking around. How can I get read of the warning message “Task was destroyed but it is pending!” that is printed in the console each time this happens ?
Here is a code example, everything is working as-intended in my opinion except for the annoying “Task was destroyed but it is pending!” messages in the console.
import asyncio
import os
import psutil
import random
import gc
async def waitForEvent(e: asyncio.Event):
# Generate a 10MB array of random bytes to see memory leaks
rand_seq = random.getrandbits(8)
random_bytes = bytearray(rand_seq for _ in range(10 * 1024 * 1024))
await e.wait()
print("event completed", random_bytes[-10:]) # Print the last 10 bytes
events = []
def startDeadCoroutine():
ev = asyncio.Event()
#events.append(ev) uncomment this to see that the task is no longer destroyed because the event is no longer eligible for garbage collection
asyncio.create_task(waitForEvent(ev))
process = psutil.Process(os.getpid())
while True:
startDeadCoroutine()
mem_info = process.memory_info()
print(f"Memory usage: {mem_info.rss / 1024 / 1024:.2f} MB")
collected = gc.collect()
await asyncio.sleep(0.1) # Add a delay```