production-taskbar / backend / tgbot / tasks.py
tasks.py
Raw
import logging
import time
from typing import Any

from asgiref.sync import async_to_sync
from celery import shared_task
from celery.exceptions import InvalidTaskError
from tgbot.handlers.utils.django import update_bot_info, update_bots_is_polling
from .application import setup_application

task_retry_delay = 30    # in sec


@shared_task(bind=True, ignore_result=False,
             max_retries=None)    # type: ignore
def start_polling(self: Any) -> None:
    """ Run bot in pooling mode """
    try:
        app = async_to_sync(setup_application)()    # type: ignore
        if app:
            bot = update_bot_info(app.bot, True)
            logging.info(f"Polling of '{bot.link}' started")
            self.update_state(state='STARTED',
                              meta={'info': 'run_polling started'})
            # start polling loop
            app.run_polling()
            # 
            update_bots_is_polling(False)
            self.update_state(state='RETRY',
                              meta={'info': 'run_polling stopped, retrying'})
            self.retry(
                countdown=task_retry_delay,
                max_retries=None,
            )
        else:
            raise InvalidTaskError('Application can`t initialize')
    except Exception as e:
        update_bots_is_polling(False)
        logging.error(f'{e}, retrying in {task_retry_delay} sec')
        time.sleep(
            task_retry_delay
        )    # prefer time.sleep to a retry.countdown because of reliability
        self.retry(
            exc=e,
            max_retries=None,
        )