Shtut
Shtut

Reputation: 1407

running asyncio task without await causes memory issue

I have a slow function call early in the run, which returns a value I do not use until much later. I do not want to await this function when I first call it.

# run start
asyncio.get_event_loop().create_task(slow_function_wrapper())

async def slow_function_wrapper(self):
  self.slow_value = await slow_function()

...
# later in the code
async def get_slow_value(self):
  if iscoroutine(self.slow_value):   #if the call still didn't finish, await it
    await self.slow_value
  return self.slow_value

my issue is, this seems to cause a memory leak. there's some reference still saved to the task, so even when it completes it does not clear it from memory.

Is there a standard way of not-awaiting async function? or clearing the reference once it's done?

This is python 3.7

Upvotes: 1

Views: 948

Answers (1)

Artiom  Kozyrev
Artiom Kozyrev

Reputation: 3836

Just use asyncio.create_task with add_done_callback

import asyncio
from functools import partial


async def slow_function() -> int:
    await asyncio.sleep(5)
    return 100


class SomeClass:
    def __init__(self):
        self.slow_value = None

    def slow_function_wrapper(self) -> None:
        task = asyncio.create_task(slow_function())  # we do not wait anything here
        task.add_done_callback(partial(callback, obj=self))


def callback(fut: asyncio.Task, obj: SomeClass) -> None:
    if fut.exception():
        print("Error")
        obj.slow_value = -1
    else:
        print("OK")
        obj.slow_value = fut.result()


async def result_pinger(obj: SomeClass) -> None:
    # we need to make asyncio loop busy with something
    while True:
        await asyncio.sleep(1)
        print(f"Result: {obj.slow_value}")
        if obj.slow_value is not None:
            break


async def main():
    x = SomeClass()
    x.slow_function_wrapper()
    await result_pinger(obj=x)  # prevent asyncio loop from stopping


if __name__ == '__main__':
    asyncio.run(main())

Upvotes: 3

Related Questions