Timer Jobs
Timer Jobs Portal
Система заданий по расписанию (аналог SharePoint Timer Jobs): разработчик пишет C#-обработчик, упаковывает в .portaltimer, администратор настраивает расписание в админке.
Обзор
- Пакеты —
.portaltimer(ZIP сmanifest.json+ C# DLL) - SDK —
Portal.TimerJob.Sdk(ITimerJob) - Шаблон —
dotnet new portal-timerjob(см.backend/templates/portal-timerjob/) - Worker — планировщик cron + очередь
portal_jobs
Документация:
- Манифест — поля
manifest.json,configSchema - SDK —
ITimerJob, контекст, API, постановка заданий в очередь - Сборка пакета —
build.sh, установка и обновление - Расширения: интеграция с Worker — жизненный цикл, отладка, API
Архитектура
Админка → timer_jobs (расписание + config) ↓CronSchedulerService (каждую минуту) → portal_jobs (pending) ↓JobQueueWorker → JobProcessor → TimerJobPackageLoader ↓ITimerJob.ExecuteAsync(context, api)| Сущность | Таблица / ключ | Описание |
|---|---|---|
| Пакет | timer_job_packages | ZIP в объектном хранилище (S3) |
| Определение | timer_job_definitions | Обработчик из manifest (job_type = manifest.id) |
| Экземпляр | timer_jobs | Конкретное задание: расписание + config |
| Выполнение | portal_jobs | Запись в очереди Worker |
Один пакет → одно определение → много экземпляров с разным расписанием и config (например, два heartbeat с разными сообщениями).
Часовой пояс планировщика — локальный сервера Worker (TimeZoneInfo.Local).
Быстрый старт (разработчик)
cd packages/timer-job-examples/heartbeat./build.shРезультат: dist/heartbeat.portaltimer → Админка → Timer Jobs → загрузить пакет.
- Создайте экземпляр задания (например, «Каждую минуту») с
config: { "message": "hello" } - Нажмите Запуск или дождитесь cron
- В логах Worker:
[timer-job] Contoso heartbeat: hello ...
Пример: packages/timer-job-examples/heartbeat/.
Быстрый старт (администратор)
- Админка → Timer Jobs — установить пакет
.portaltimer - Убедиться, что служба
timer-extensionsвключена и Worker запущен (docker compose up -d worker) - + Timer Job — выбрать обработчик, расписание, параметры
config - Запуск — ручной запуск без ожидания cron
- Админка → Задания — статус выполнения (
pending→completed/failed)
При установке или удалении пакета API уведомляет Worker через Valkey — перезапуск контейнера не нужен.
Timer Job vs Event Receiver
| Timer Job | Event Receiver | |
|---|---|---|
| Триггер | Расписание (cron) | Событие домена (listItem.updated) |
| Пакет | .portaltimer | .portalevent |
| Контракт | ITimerJob | IEventReceiver |
| API в обработчике | Лог + постановка jobs | Списки, узлы, jobs |
| Типичный сценарий | Ночная синхронизация, отчёты | Реакция на изменение элемента |
Для реакции на события используйте Event Receivers. Для периодических задач — Timer Jobs.