ekonda / kutana

The library for developing systems for messengers and social networks
MIT License
72 stars 17 forks source link

[Вопрос] Не делать ожидание в некоторых плагинах. #62

Closed daeeros closed 3 years ago

daeeros commented 3 years ago

У нас есть такой плагин рассылки, но при его работе все остальные пользователи так же ждут пока он завершится, тк как бот не будет обрабатывать их учитывая что он асинхронный, подскажите как можно не делать ожидание завершения в некоторых плагинах и сразу же давать возможность боту обрабатывать следующие сообщения/плагины?

from kutana import Plugin, RequestException

plugin = Plugin()

@plugin.on_commands(["test"])
async def __(msg, ctx):

    await ctx.reply("Начинаю рассылку.")

    members = []
    offset = 1000

    data = await ctx.request("groups.getMembers", sort="time_asc", group_id="1")
    members += data['items']

    steps = int(data['count'] / 1000)

    for _ in range(steps):
        data = await ctx.request("groups.getMembers", sort="time_asc", group_id="1", offset=offset)
        members += data['items']
        offset += 1000

    sended = 0
    for u in members:
        try:
            await ctx.send_message(u, text="У нас тут новая запись!", attachment="wall-1_1")
            sended += 1
        except RequestException:
            continue

    return await ctx.reply("Рассылка завершена! Всего отправлено: {}".format(sended))
michaelkryukov commented 3 years ago

Простой плагин, который много спит (асинхронно):

import asyncio
from kutana import Plugin, t

plugin = Plugin(
    name=t("Bruh"),
    description=t("Sleeps in a loop"),
)

@plugin.on_commands(["bruh"])
async def __(msg, ctx):
    for __ in range(10):
        await asyncio.sleep(1)
        await ctx.reply("bruh")

image

Как видно из скриншота, во время обработки плагином сообщения другие сообщения без проблем обрабатываются ботом благодаря асинхронности происходящего. У kutana есть ограничение в 512 (можно указать другео число в concurrent_handlers_count) на количество парралельно обрабатываемых сообщения (чтобы избежать дудоса и переполнения памяти). У бекенда вконтакте есть ограничение на 19 запросов в секунду (всего 19 * 25 = 475 сообщений в секунду). Если рассылка поглощает этот лимит - то не существует способа "не ожидать завершения рассылки". Только создавать отдельные токены, которые будут выполнять рассылку.