Почему apscheduler продолжает работать в течение длительного времени?

Здравствуйте! Я разрабатываю Telegram-бота на aiogram 3 и столкнулся с проблемой отложенной отправки сообщений пользователям через 3 дня после их регистрации. При тестировании с таймдельтой в 10 секунд всё работало, однако на продакшене, когда я установил таймдельту на 3 дня, шедулер не срабатывает, и задачи в Redis jobstore удаляются до выполнения функции. <br/><b><br/> 
Вот как я инициализирую шедулер:</b> <br/> <pre><code class="python"># Внешние библиотеки
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.schedulers.asyncio import AsyncIOScheduler

# Инициализация редис, куда будут сохраняться рассылки
jobstores = {"default": RedisJobStore(host="localhost", port=6379, db=3)}</code></pre> <br/><br/> 
<b>Модуль шедулера:</b> <br/> <pre><code class="python"># Стандартные библиотеки
import asyncio
from datetime import datetime
import json

# Внешние библиотеки
from aiogram.fsm.storage.base import StorageKey
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import FSInputFile

router = Router() 
message_queue = asyncio.Queue()

# Функция-работник для отправки сообщений из очереди
async def message_sender_worker(redis_middleware):
    while True:
        user_id = await message_queue.get()
        try:
            # Создаем ключ и контекст состояния для пользователя
            key = StorageKey(bot_id=bot.id, chat_id=user_id, user_id=user_id)
            state = FSMContext(storage=dp.storage, key=key)

            # Получаем язык пользователя из Redis
            user_lang = await redis_middleware.get(f"user_lang:{user_id}")
            user_lang = user_lang if user_lang else "ru"  # По
  • 8 октября 2024 г. 7:35
Ответы на вопрос 2
Проблема с тем, что задачи в APScheduler не запускаются, скорее всего связана с конфигурацией и настройками вашего шедулера. Вот несколько возможных причин и решений:

1. **Проверка конфигурации шедулера**: Убедитесь, что шедулер действительно запущен и работает. Вы можете добавить несколько строк кода, чтобы проверить его состояние:
    ```python
    scheduler = AsyncIOScheduler(jobstores=jobstores)
    scheduler.start()  # Запускаем шедулер
    print("Scheduler started")
    ```

2. **Правильная инициализация и добавление задач**: Когда вы добавляете задачи в шедулер, убедитесь, что вы указываете параметры корректно, включая `trigger`, `run_date` и `args`. Например:
    ```python
    from datetime import timedelta

    # Добавление задачи
    run_time = datetime.now() + timedelta(days=3)
    scheduler.add_job(my_job_function, run_date=run_time, args=[user_id])
    ```

3. **Проблемы с Redis**: Убедитесь, что Redis работает и вы можете к нему подключиться. Проверьте наличие записей в вашем jobstore, чтобы подтвердить, что задачи правильно сохраняются.

4. **Логи и отладка**: Добавьте логи в ваши функции и в задачи шедулера, чтобы понять, нормально ли они выполняются. Это может помочь выявить, выполняется ли задача, но происходит ли ошибка где-то внутри.
    ```python
    async def my_job_function(user_id):
        print(f"Running task for {user_id}")
        # Остальной код функции
    ```

5. **Проверьте время**: Когда вы используете `timedelta`, будьте внимательны в отношении временных зон. Если ваш сервер и Redis настроены на разные временные зоны, это может привести к тому, что задачи не будут запускаться вовремя. Укажите явным образом временную зону, если это необходимо.

6. **Использование других типов хранилищ**: Если проблема всё ещё возникает, вы можете попробовать использовать другие хранилища (например, SQLite или SQLAlchemy) для проверки, связано ли это именно с Redis.

7. **Обновления версий**: Убедитесь, что версии библиотеки APScheduler и RedisJobStore актуальны, и нет известных багов в вашей версии.

Если после проверки всего вышеперечисленного проблема не исчезает, больше информации о ваших задачах и настройках, а также о том, как вы тестируете их выполнение, может помочь в отладке.
Так как ты не показал инициализацию scheduler, то спрошу: scheduler.start() не забыл вовремя вызвать? 
Также есть совет увеличить детализацию логов для скедулера.
Похожие вопросы