ekonda / kutana

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

Добавить новый декоратор "schedule" #78

Closed daeeros closed 1 year ago

daeeros commented 1 year ago

Довольно часто требуется запускать постоянные coroutines эное-кол-во раз в несколько секунд. Текущий подход всегда выглядел так, несомненно работает нет проблем. Но как бы это удобно выглядело с декоратором?

from kutana import Plugin
import asyncio

plugin = Plugin("TestPlugin")

@plugin.on_start()
async def _():
    asyncio.create_task(egg_printer())

# Prints egg every 5 seconds
async def egg_printer():
    while True:
        print("Its Egg!")
        await asyncio.sleep(5)

Вот как бы это выглядело с помощью декоратора, красиво а самое главное удобно. И мы избавляемся от лишних импортов и лишних блоков кода.

from kutana import Plugin

plugin = Plugin("TestPlugin")

# Prints egg every 5 seconds
@plugin.schedule(5)
async def egg_printer():
    print("Its Egg!")
michaelkryukov commented 1 year ago

С таким минимальным примером действительно выглядит поаккуратнее. Мне кажется, что реализация в #79 простая и рабочая, но можно повысить полезность, если услышать реальные сценарии использования такой фичи. Можно их услышать?

daeeros commented 1 year ago

С таким минимальным примером действительно выглядит поаккуратнее. Мне кажется, что реализация в #79 простая и рабочая, но можно повысить полезность, если услышать реальные сценарии использования такой фичи. Можно их услышать?

На самом деле реализаций много, к примеру тот же таймер

@pl.schedule(1)
async def TimerChecker():
    # First check lobby
    to_delete_lobby = []
    for lobby in pl.lobbys:
        if lobby.timer.is_over:
            to_delete_lobby.append(lobby)

    for lobby in to_delete_lobby:
        del pl.lobbys[pl.lobbys.index(lobby)]

    await asyncio.gather(*[pl.app._backends[0].send_message(l.chat_id, f"⌛ • {pl.u.mention(l.creator.id, l.creator.name)} к сожалению в вашем лобби не набралось достатачное кол-во игроков за 5 минут, "
                        "оно было удалено, вы можете создать новое лобби и попытать удачу сного.") for l in to_delete_lobby])

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

michaelkryukov commented 1 year ago

Получается для приведённого примера как раз такая реализация не очень хороша - вместо того, чтобы выполнять 300 проверок, достаточно один раз подождать 5 минут. Да и зачем обновлять курс валют, если никто не использует команду, которая как-то использует эту информацию? Поэтому как раз покрутить хочется.

daeeros commented 1 year ago

Получается для приведённого примера как раз такая реализация не очень хороша - вместо того, чтобы выполнять 300 проверок, достаточно один раз подождать 5 минут. Да и зачем обновлять курс валют, если никто не использует команду, которая как-то использует эту информацию? Поэтому как раз покрутить хочется.

Тут да соглашусь что нет смысла обновлять, пока никто не использует, на я думаю у этой ситуации 2 стороны медали,

  1. Да обновлять только при команде пользователя и так же чекать время старого апдейта,
  2. Но тогда пользователь как раз таки будет ждать пока этот курс обновится, даже если какие то 500мс, это тоже время, а значит на ответ понадобиться больше времени. Поэтому я думаю что выполнять такие задачи в фоне независимо от пользователя, как раз таки хороший выбор, опять же задачи могут быть даже тяжелые которые выполняться могут 5 секунд а то и до минуты, и заставлять ждать юзера пока это всё обновится как мне не лучшая затея.