When using asyncio and aiohttp, faced this issue and was wondering if it was an occurance limited to VSC only?
This one keeps leaving residues from the previous loops.
while True:
loop.run_until_complete(get_data())
This runs without any residual tasks.
while True:
asyncio.run(get_data())
session = aiohttp.ClientSession()
async def fetch(url, params=None):
async with semaphore:
async with session.get(url, params=params) as response:
return await response.json()
I tried moving the while loop inside the called method itself but still the same result. Also tried using semaphores with no better luck.
I was trying to manage multiple rest api call methods using aiohttp from within a single loop but with this happening, guess I am stuck with having to use asyncio.run separately for each api related method. So the only way to avoid this right now is to keep closing and reopening separate loops? Could this possibly be a VSC related issue?
Edit: Tried something with Python 3.10.6 and VSCodium. I don’t know if it’s because this one shows tasks/loops instead of threadpool here but the same issue is not replicated. The increment issue still persists when using Python 3.10.6 with VS Code. So could this be either 1) VSC issue as suspected or 2) just that the call stacks are being treated different between the two IDEs?
while True:
asyncio.run(get_data())
Another thing to note is that the ThreadPoolExecutor
stacking when using VSC, stops exactly at the 20th stack: ThreadPoolExecutor-0_19
. Then no more increments and no crashes.
2
Answers
This worked. Still not sure as to the different results between VSC and VSCodium with the initial code but nonetheless, for anyone else who stumbles through.
Note: Python 3.7 was end-of-lifed in 2023. Neither Python nor VS Code will make fixes for such an old version if it ended up being the case. Also,
asyncio
has undergone a lot of changes over the various Python versions.In answer to your question,
loop.run_until_complete
is a low-level event loop function. The event loop isn’t being cleaned up because you are also not calling the required low-level loop management functions, likeloop.stop
andloop.close
and possibly others.asyncio.run
is a high-level function that does all of this for you, which is why the loop is being cleaned up after it runs.I don’t think this comment is accurate in terms of event loop tasks, since tasks has a specific meaning. It looks like it’s just
ThreadPoolExecutors
getting left behind. The event loop doesn’t run on this executor, and thus no tasks will. The executor is used for things likeasyncio.to_thread
orloop.run_in_executor
(not sure if Python 3.7 has either of those). It’s getting left behind because the event loop creates one when it starts.