← Cache & Workers

Планировщик

cache-workers · workzone

Кто запускает задачи по времени. Триггеры по расписанию рождаются здесь; событийные триггеры (модуль зовёт очередь напрямую) — мимо планировщика. Куда задача попадает и кто её разгребает — в трёх лейнах; что гасит двойной запуск — единственность.

Планировщик

Встроенный cron SAQ. SAQ умеет CronJob из коробки — второй планировщик не нужен. Он живёт на выделенном singleton-сервисе (одна реплика), отдельном от горизонтально масштабируемого пула воркеров: будь cron на каждом воркере, при N репликах он сработал бы N раз. Планировщик лишь публикует задачу в лейн — исполняют воркеры.
Singleton · 1 реплика
Планировщик
cron SAQ · тикает по расписанию
публикует, не исполняет
Пул · N реплик (горизонтально)
Воркер
Воркер
Воркер
разгребают лейны параллельно

Планировщик питают два источника триггера — оба публикуют в лейн, дальше путь у задачи общий:

фиксированный cron
CronJob по календарю — один тик публикует одну задачу: sync, reconcile, health-проба, доводка, бэкап.
скан next_run_at
Периодический проход по расписаниям агентов — один скан публикует все прогоны, чей next_run_at уже наступил. Время задаёт владелец, планировщик лишь будит.
Идеальная надёжность не требуется — в обе стороны. Двойной тик (рестарт, гонка) безопасен: его гасит замок единственности в Postgres — первый прогон стартует, второй ловит конфликт и уходит в skipped. Пропущенный тик (singleton лежал в плановое окно) тоже допустим — backfill не делаем, ждём следующего окна: каденсы грубые, один пропуск навёрстывает следующий прогон. Планировщик отвечает за «когда», корректность одного экземпляра — за единственностью.
Окна — в таймзоне организации, тик — в UTC. Расписания хранятся naive, без зоны (HH:MM, минута недели). В момент запуска планировщик разворачивает окно к UTC через platform_settings.timezone (IANA); расписания агентов — через timezone владельца (NULL → пояс организации). Единый контракт платформы: задаём и показываем в локальном времени, храним и тикаем в UTC — как в Harvester и Agent Engine.
Расписания v1 — простые: «каждые N часов», «еженедельно в HH:MM». Богатый / динамический cron (per-источник окна, правка из UI) — v2.

Реестр расписаний

Расписание Каденс Лейн Потребитель
Incremental sync 6 ч (webhooks) / 15 мин (polling-only) background → Harvester
Reconcile еженедельно background → Harvester
Health-проба источников раз в сутки background → Harvester
Curation pass одно платформенное расписание background → Knowledge Store
Backup своё расписание background → Knowledge Store
Скан агентов планировщик сканирует next_run_at agents → Agent Engine
Переэмбеддинг KS ставится событием — сменой модели, а не только по cron: смена дёргает прогон сразу, расписание здесь его не держит.