Reputation: 45
I have a script in which a Slow and a Fast function processes the same global object array. The Slow function is for filling up the array with new objects based on resource intensive calculations, the Fast is only for iterating the existing objects in the array and maintaining/displaying them. The Slow function only needs to be run only in every few seconds, but the Fast function is imperative to run as frequently as possible. I tried using asyncio and ensure_future calling the Slow process, but the result was that the Fast(main) function ran until I stopped it, and only at the end was the Slow function called. I need the Slow function to start running in the instance it is called in the background and complete whenever it can, but without blocking the call of the Fast function. Can you help me please? Thank you!
An example of what I tried:
import asyncio
variable = []
async def slow():
temp = get_new_objects() #resource intensive
global variable
variable = temp
async def main():
while True: #Looping
if need_to_run_slow: #Only run sometimes
asyncio.ensure_future(slow())
do_fast_stuff_with(variable) #fast part
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
Upvotes: 0
Views: 277
Reputation: 154846
asyncio.ensure_future(slow())
only schedules slow()
to run at the next pass of the event loop. Since your while
loop doesn't await anything that can actually block, you are not giving the event loop a chance to run.
You can work around the issue by adding an await asyncio.sleep(0)
after the call to the fast function:
async def main():
while True:
if need_to_run_slow:
asyncio.ensure_future(slow())
await asyncio.sleep(0)
do_fast_stuff_with(variable)
The no-op sleep will ensure that at every iteration of the while
loop (and between runs of the "fast" function") gives a chance for a previously scheduled slow()
to make progress.
However, your slow()
doesn't await either, so all of its code will run in a single iteration, which makes the above equivalent to the much simpler:
def main():
while True:
slow() # slow() is an ordinary function
do_fast_stuff_with(variable)
A code example closer to your actual use case would probably result in a more directly usable answer.
Upvotes: 2