Я пытаюсь написать небольшой обработчик параллельного потока с помощью Slack RTM API, и мне интересно, является ли это наиболее эффективным использованием сопрограмм Python. Пакет asyncio
имеет массу опций, но трудно определить, какой подход является правильным для проекта, и документация, я думаю, не очень хорошо объясняет, в чем преимущества/недостатки каждого из них.
Я думаю, что мне не нужны накладные расходы на несколько потоков, и мне нужна взаимосвязь между асинхронными циклами. Должен ли я создать отдельный BaseEventLoop
для каждой из моих функций?
Будучи Python, я думаю, что здесь есть почти-детерминированный ответ на этот вопрос (There should be one-- and preferably only one --obvious way to do it
), но я боюсь, что добавление всего этого асинхронного хлама может просто сделать мой код менее производительным, чем полностью последовательная наивная реализация .
# Is this the best way to communicate between coroutines?
incoming_message_q = asyncio.Queue()
async def print_event():
logging.info("Entering log loop")
# Should this operate within it's own BaseEventLoop?
while True:
event = await incoming_message_q.get()
logging.info(event)
async def log_queue_status():
while True:
logging.info(incoming_message_q.qsize())
await asyncio.sleep(5)
async def read_rtm_connection(client, q):
if client.rtm_connect():
logging.info("Successful Slack RTM connection")
while True:
# How do I make this part non-blocking?
events = client.rtm_read()
for event in events:
logging.info("Putting onto the queue", event)
if event["type"] == "presence_change":
await q.put(event)
elif event["type"] == "message":
await q.put(event)
else:
logging.info("Not sure what to do")
await asyncio.sleep(0.1)
else:
logging.info("RTM connection failed.")
loop = asyncio.get_event_loop()
loop.create_task(print_event())
loop.create_task(log_queue_status())
loop.create_task(read_rtm_connection(client, incoming_message_q))
loop.run_forever()