Reputation: 1407
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
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