How to combine two asynchronous libraries?

How can I combine two asynchronous libraries in the same program?

In context, I want to use Discord api with aiohttp, both of which are asynchronous event loops. Maybe I want to add the async irc library to the mix as well.

However, I do not understand how they will work together. I believe that theoretically I would implement the program in such a way that all instances of the class use the same instance of the asyncio event loop, and then combine all the launch functions together into one, ultimately triggering an event loop.

However, I would like to know if there is any more elegant way to do this?

+4
source share
1 answer

As long as all libraries use the same eventloop, they will work well together. In this case, it seems that all the libraries you have selected are based on asyncio (excetp gawel IRC lib, which is no longer available). So there are no problems. There is one eventloop (and no threads), and all is well.

The problem that you are facing is that you will have multiple “servers” in the same event loop, or rather, there are several coroutines that handle input from the outside world. One coroutine handles HTTP traffic, and the other handles IRC traffic. In pseudo-code, it can be translated into the following:

import asyncio


@asyncio.coroutine
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

@asyncio.coroutine
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(irc_server())

loop.run_forever()

, . HTTP- IRC, - . - , , . - :

import asyncio


# value is shared between IRC and the web server.
value = None


@asyncio.coroutine
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

@asyncio.coroutine
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(irc_server())

loop.run_forever()
+1

Source: https://habr.com/ru/post/1663858/


All Articles