skip to Main Content

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())

enter image description here

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.

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    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.

    async def fetch(url, params=None):
         if not self.session:
             self.session = aiohttp.ClientSession()
         async with semaphore:
             async with session.get(url, params=params) as response:
                 return await response.json()
    
    async def get_data(self):
         json_response = await self.fetch("https://jsonplaceholder.typicode.com/todos/1")
    
    while True:
         asyncio.run(get_data())
    

  2. 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, like loop.stop and loop.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.


    This runs without any residual tasks.

    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 like asyncio.to_thread or loop.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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search