Как запустить шедулер aioschedule, не блокируя asynctelebot

Рейтинг: 0Ответов: 1Опубликовано: 12.04.2023

Всем привет! Пишу телеграм бот на AsyncTelebot, столкнулся с такой проблемой, что не удается запустить шедулер, не блокируя работу бота. Есть следующий фрагмент кода:

import asyncio
import aioschedule as schedule

...

async def send_price_update_notifications():
    print("Check notifications: " + str(datetime.datetime.now()))
    ...

async def send_notifications():
    await send_price_update_notifications()


async def run_notifications():
  
    schedule.every(10).seconds.do(send_notifications)

    while True:
        await schedule.run_pending()
        await asyncio.sleep(0)

async def start_bot():
    while True:
        await bot.polling(none_stop=True)
        await asyncio.sleep(0)

async def main():

    task1 = asyncio.create_task(run_notifications())
    task2 = asyncio.create_task(start_bot())

    await asyncio.gather(task1, task2)


if __name__ == '__main__':
    asyncio.run(main())

В результате шедулер выполняется, а бот в телеграме на запросы не реагирует. При отключении шедулера бот снова начинает работать. Разбирался с конкурентным выполнением кода и asyncio, вроде как возвращаю управление из каждой корутины в конце выполнения в общий event loop, но, судя по всему, не до конца разобрался и не вижу каких-то деталей. Подскажите, пожалуйста, куда копать?

введите сюда описание изображения

введите сюда описание изображения

Ответы

▲ 0

Помогло вынесение шедулера в отдельный поток через threading и использование schedule вместо aioschedule, запуск поллинга вынес из функции.

import schedule as schedule
...

def run_notifications():
    schedule.every(notification_period).seconds.do(send_notifications)

async def main():
    t1 = threading.Thread(target=run_notifications)
    t1.daemon = True
    t1.start()

if __name__ == '__main__':
    asyncio.run(main())

while True:
    try:
        asyncio.run(bot.polling(none_stop=True, skip_pending=False))

    except Exception as _ex:
        print(_ex)
        sleep(15)