I have a coroutine as follows:
async def download():
downloader = DataManager()
downloader.download()
DataManager.download()
method looks like:
def download(self):
start_multiple_docker_containers()
while True:
check_containers_statuses()
sleep(N) # synchronous sleep from time module
Is this a good practice? If no, how can I use asyncio.sleep
in download()
?
Or maybe such code structure is conceptually wrong?
It's most likely a bad practice, as time.sleep() will block everything, while you only want to block the specific coroutine (i guess).
you are making a sync operation in async world.
What about the following pattern?
Here's my solution:
Results in:
As for the
sleep()
function - no, you shouldn't use it. It blocks the whole python interpreter for 1 second, which is not what you want.Remember, you don't have parallelism (threads etc.), you have concurrency.
I.e. you have a python interpreter with just 1 thread of execution, where your main loop and all your coroutines run, preempting each other. You want your interpreter to spend 99.999% of its working time in that main loop, created by asyncio, polling sockets and waiting for timeouts.
All your coroutines should return as fast as possible and definitely shouldn't contain blocking
sleep
- if you call it, it blocks the whole interpreter and prevents main loop from getting information from sockets or running coroutines in response to data, arriving to those sockets.So, instead you should await
asyncio.sleep()
which is essentially equivalent to Javascript'ssetTimeout()
- it just tells the main loop that in certain time it should wake this coroutine up and continue running it.Suggested reading:
I'm new at asyncio, but it seems that if you run sync code like this
f = app.loop.run_in_executor(None, your_sync_function, app,param1,param2,...)
then
your_sync_function
is running in a separate thread, and you can dotime.sleep()
without disturbing the asyncio loop. It blocks the loop executor's thread, but not the asyncio thread. At least, this is what it seems to do.If you want to send messages from
your_sync_function
back to asyncio's loop, look into thejanus
libraryMore tips on this:
https://carlosmaniero.github.io/asyncio-handle-blocking-functions.html