2016-12-15 3 views
4

Как я мог бы объединить две библиотеки асинхронных в той же программе?Как объединить две асинхронные библиотеки?

Для контекста, я хочу использовать Discord api с aiohttp, оба из которых являются асинхронными циклами событий. Возможно, я хочу добавить библиотеку async irc в микс.

Однако я не понимаю, как они будут работать вместе. Я полагаю, что в теории я бы реализовал программу таким образом, чтобы все экземпляры класса использовали один и тот же экземпляр цикла событий asyncio, а затем объединяли все функции запуска вместе в один, в конечном счете вызывая цикл событий.

Однако, я хотел бы знать, есть ли вообще более элегантный способ сделать это?

+0

Это зависит от того, какие библиотеки вашего используете именно благодаря совместимости события петлями –

+0

Ну тогда, принимая во внимание три: aiohttp, диссонанс апи связаны выше, и, возможно, https: //github.com/gawel/irc? Хотя, честно говоря, я надеялся, что будет какой-то общий, элегантный способ сделать это. – Firnagzen

+1

Я думаю, что ты на правильном пути. вы должны иметь возможность просто установить один и тот же цикл событий для всех, но это не kludge, чтобы иметь сопрограммы из разных библиотек, управляемых из одного цикла событий. – acushner

ответ

1

Пока все библиотеки используют один и тот же eventloop, они будут хорошо работать вместе. В этом случае кажется, что все выбранные вами библиотеки основаны на asyncio (IRC lib от excetp gawel, который больше не доступен). Так что проблем нет. Существует один eventloop (и без потоков), и все хорошо.

Проблема, с которой вы сталкиваетесь, заключается в том, что у вас будет несколько «серверов» в одном и том же цикле событий или, точнее, есть несколько сопрограмм, которые обрабатывают ввод из внешнего мира. Один сопрограммы обрабатывает HTTP-трафик, а другой обрабатывает IRC-трафик. В псевдо-коде, он может быть переведен на следующее:

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() 
+0

На самом деле IRC IRC3 теперь называется IRC3 https://github.com/gawel/irc3/ – amirouche

Смежные вопросы