How would I go about combining two asyncio libraries in the same program?
For context, I wish to use the Discord api with aiohttp, both of which are async event loop driven. I may potentially want to add an async irc library to the mix, too.
However, I don't understand how they would be operated together. I believe that in theory I would implement the program such that all class instances utilise the same asyncio event loop instance, and then kludge all the run functions together into one, ultimately calling the event loop.
However, I would like to know if there is in general a more elegant way of doing this?
The intended use of asyncio tasks is to allow independently running tasks to run 'concurrently' with other tasks within the same event loop.
As long as all the libraries use the same eventloop they will work together nicely. In this case it seems like all the libraries you choosed are based on asyncio (excetp gawel's IRC lib which is not available anymore). So there is no problem. There is a single eventloop (and no threads) and all is well.
The problem you face is that you will have several "servers" in the same event loop or more accuratly there is several coroutines that handle input from the outside world. One coroutine is handling the HTTP traffic and the other is handling the IRC "traffic". In pseudo-code, it can be translated to the following:
import asyncio
async def irc_server():
async with irc_connect('irc.freenode.net#python-fr') as irc:
async for message in irc:
# do something useful with message
async def web_server():
async with web_connect('localhost:8080') as web:
async for request in web:
# do something useful with request
loop = asyncio.get_event_loop()
loop.create_task(irc_server())
loop.create_task(web_server())
loop.run_forever()
As such, both coroutines have no way to communicate. To make the HTTP part communicate with the IRC part you have to share something between the two coroutines. In production it's prolly somekind of database but in pseudo code, it's a simple global. You will end up with something like that:
import asyncio
# value is shared between IRC and the web server.
value = None
async def irc_server():
global value
async with irc_connect('irc.freenode.net#python-fr') as irc:
async for message in irc:
# if message is echo, reply with the current value
# otherwise store the message as value
if message == 'echo':
irc.send(value)
else:
value = message
async def web_server():
global value
async with web_connect('localhost:8080') as web:
async for request in web:
if request.path == 'echo':
request.client.send(value)
else:
value = request.path # this is silly but simple
loop = asyncio.get_event_loop()
loop.create_task(irc_server())
loop.create_task(web_server())
loop.run_forever()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With