Asyncio sleep blocking coroutines - python

I have this code :
import asyncio
import aioconsole
async def imp():
print("Cool I'm printing")
await asyncio.sleep(2)
await imp()
async def console():
while True:
comm = await aioconsole.ainput(">>")
if 'cool' in comm:
await imp()
async def main():
console_use = asyncio.create_task(console())
await console_use
if __name__ == '__main__':
try:
asyncio.run(main())
except AttributeError:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
The problem is that when the code enter to the function imp() the console() function stops working and I would like to continue using the console for other functions. How can I solve that?
Ps. I tried doing threads, create tasks and nothing is working...

Related

Python run 2 async infinite loops after the first one already started

I want to run 2 infinite async loops that should run simultanoesly.
However though, they are not called together.
The first loop starts running immediately and when it detects something it calls the second loop and they should run independently.
Something like this:
async def test():
while True:
print("test")
time.sleep(7)
async def call_test():
loopd = asyncio.get_running_loop()
task = loopd.create_task(test())
await task
async def print_main():
while True:
print("main")
await call_test()
time.sleep(5)
def main():
loop = asyncio.get_event_loop()
loop.create_task(print_main())
loop.run_forever()
if __name__ == '__main__':
main()
PS:
There are a lot of similar questions, but they all run 2 independent loops from the start.
You should not use time.sleep with asyncio loop in the same thread, otherwise time.sleep will block all other tasks of the asyncio loop.
You need only one asyncio loop in one thread, because only one loop can do work simultaneously in the same thread.
Your code will work with the following changes:
import asyncio
async def test():
while True:
print("test")
await asyncio.sleep(7)
async def print_main():
another_task = None
while True:
print("main")
if another_task is None:
another_task = asyncio.create_task(test())
await asyncio.sleep(5)
def main():
loop = asyncio.get_event_loop()
loop.create_task(print_main())
loop.run_forever()
if __name__ == '__main__':
main()

Add multithreading layer to Asyncio

I currently have this piece of code running just fine using AsyncIO.
async def main():
while(1):
loop.create_task(startAsyncJob())
await asyncio.sleep(1)
async def startAsyncJob():
#myCodeHere
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
I tried to add a multithreading layer so I can run concurrently multiple pieces of what inside my "main". So I extracted its code, put it in its own function AsyncJobThread that I launch through my new main function using threads:
def main():
try:
_thread.start_new_thread( AsyncJobThread, (1))
_thread.start_new_thread( AsyncJobThread, (15))
except:
print ("Error: unable to start thread")
async def AsyncJobThread(frequence):
while(1):
loop.create_task(startAsyncJob())
await asyncio.sleep(frequence)
async def startAsyncJob():
#myCodeHere
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
However the current implementation gives me the following error:
sys:1: RuntimeWarning: coroutine 'AsyncJobThread' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
As requested, here's your code modified to use asyncio.gather.
async def main():
await asyncio.gather(
AsyncJobThread(1),
AsyncJobThread(15),
)
async def AsyncJobThread(frequence):
loop = asyncio.get_event_loop()
while True:
loop.create_task(startAsyncJob())
await asyncio.sleep(frequence)
async def startAsyncJob():
#myCodeHere
asyncio.run(main())
You could also get a reference to the loop and pass it into AsyncJobThread if you prefer.

How to nest asyncio tasks in groups and sub groups?

I want to create multiple nested asyncio task groups. I don't want to use trio nursery also subtasks may contain async generators. However, I am encountering some problems:
Exiting with keyboard interrupt causes could not close task as event loop in closed
Sometimes tasks get cancelled and program gets stuck but this rarely happens
I want to make sure they everything is properly close as I am working with files and sockets
How can I fix those problems?
import asyncio
from asyncio.tasks import Task
from contextlib import AsyncExitStack
from os import error
async def cancel_tasks(tasks: set):
task: Task
for task in tasks:
await task.cancel()
async def demo_producer(queue: asyncio.Queue):
while True:
await queue.put()
async def demo_consumer(queue: asyncio.Queue):
while True:
await queue.get()
async def demo_task():
while True:
await asyncio.sleep(2) # Do Something
async def demo_task_grp(qns_queue: asyncio.Queue, ans_queue: asyncio.Queue):
async with AsyncExitStack() as stack:
tasks = set()
stack.push_async_callback(cancel_tasks, tasks)
task = asyncio.create_task(demo_producer(qns_queue))
tasks.add(task)
task = asyncio.create_task(demo_consumer(ans_queue))
tasks.add(task)
task = asyncio.create_task(demo_task())
tasks.add(task)
asyncio.gather(*tasks)
async def question_func(qns_queue: asyncio.Queue, ans_queue: asyncio.Queue):
while True:
try:
await demo_task_grp(qns_queue, ans_queue)
except error:
print(error)
finally:
await asyncio.sleep(2) # retry
async def answer_func(qns_queue: asyncio.Queue, ans_queue: asyncio.Queue):
while True:
try:
await demo_task_grp(qns_queue, ans_queue)
except error:
print(error)
finally:
await asyncio.sleep(2) # retry
async def main():
# await mqtt_setup()
# asyncio.ensure_future(mqtt_setup())
async with AsyncExitStack() as stack:
question_queue = asyncio.Queue()
answer_queue = asyncio.Queue()
tasks = set()
stack.push_async_callback(cancel_tasks, tasks)
task = asyncio.create_task(question_func(question_queue, answer_queue))
tasks.add(task)
task = asyncio.create_task(answer_func(question_queue, answer_queue))
tasks.add(task)
asyncio.gather(*tasks)
asyncio.run(main())

How to make async code run on startup - Python

Heyy,
how would I make my asynchronous code run on startup?
So this is the easiest example I could think of to make.
async def mainMenuCLI():
print("This is the CLI")
And I want the asynchronous mainMenuCLI to run on startup but I don't want it to take as many tasks because I'm not sure what is the max :(
I need it to be async because of async_input, discord.py and stuff, just don't tell me to make it sync, thanks!
If I understand your question... Do you need something likethis?
import asyncio
async def async_example():
print("hellooooo, I'm an async function")
async def main():
asyncio.Task(async_example())
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
You can add some tasks outside the async func if you need:
import asyncio
async def async_example():
print("hellooooo, I'm an async function")
await asyncio.sleep(1)
print("async function done")
async def main():
asyncio.Task(async_example())
print('This is before wait')
await asyncio.sleep(1)
print('This is after await')
await asyncio.sleep(1)
print('Ok, goodbye')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
*Note: if your py version is prior to 3.7, change asyncio.Task per asyncio.ensure_future.

How to use python async task without await

I use async create_task to run my task in background, but my_task() method not be executed.
async def my_task():
print("starting my task...")
time.sleep(2)
print("finished my task.")
if __name__ == '__main__':
print("1111")
loop = asyncio.get_event_loop()
loop.create_task(my_task())
print("2222")
the result is
1111
2222
There is a simple fix for this, but you still need to use await which you cannot avoid because create tasks returns a coroutine
import asyncio
async def my_task():
print("starting my task...")
await asyncio.sleep(2)
print("finished my task.")
if __name__ == '__main__':
print("1111")
loop = asyncio.get_event_loop()
loop.run_until_complete(my_task())
# or use can use asyncio.run(my_task())
print("2222")
EDIT: Made changes for pyfile, instead of notebook, thanks user4815162342 for pointing out

Categories