Когда говорят про запуск планировщика задач (CRON), в голове сразу возникает образ сложной инфраструктуры, дополнительных серверов и бесконечной рутины. В новой статье на блоге Wasp показали, как легко избавиться от этих сложностей, используя лишь PostgreSQL и немного волшебства от Wasp и PgBoss.
Давайте разберёмся, что это за подход и почему он действительно может облегчить жизнь разработчикам.
🧩 Проблема классических подходов
Обычно для планирования задач используется отдельный инструмент вроде CRON, Celery или Airflow. Но у таких решений есть минусы:
- 🏗️ Отдельная инфраструктура: вам нужно поднимать дополнительные серверы и сервисы.
- 🌀 Повышенная сложность: настройка и поддержка такого решения усложняют архитектуру и увеличивают вероятность сбоев.
- 🐞 Сложности отладки: поиск и решение проблем занимают больше времени.
Для простых задач это выглядит как попытка забить гвоздь микроскопом.
🎯 Решение проблемы: PostgreSQL + PgBoss + Wasp
PgBoss — это простая, но мощная система очередей задач, работающая поверх PostgreSQL. В отличие от решений на основе Redis, PgBoss не требует дополнительной инфраструктуры:
- 📚 Транзакционная надёжность: задачи переживают перезагрузку и краш приложения.
- ♻️ Повтор попыток и таймауты: автоматически перезапускает задачи при сбоях.
- 📅 Поддержка CRON: повторяющиеся задачи с простой настройкой.
Wasp — это новый фреймворк для React и Node.js, упрощающий создание веб-приложений. С помощью Wasp интеграция с PgBoss становится ещё удобнее:
- 📝 Декларативное описание задач: вы просто описываете задачи в конфигурационном файле Wasp.
- 🚀 Отсутствие рутины: автоматическая настройка очередей и рабочих процессов.
- 🔎 Типобезопасность: меньше ошибок и проще поддерживать код.
🚦 Когда стоит использовать этот подход?
Для большинства небольших проектов это идеальное решение:
- ✅ До 1000 задач в день.
- ✅ Простые операции: отправка писем, обновление записей в базе и т.д.
Но если у вас много задач или тяжёлые вычисления (обработка изображений, анализ данных), стоит подумать об отдельном сервисе задач, чтобы не нагружать основное приложение.
🛠️ Как это выглядит на практике?
Разберём два типичных примера:
⏳ Однократные задачи (Scheduled tasks)
Представим приложение для учёта результатов теннисных матчей, в котором надо отправить пользователю письмо с итогами матчей в заданное время:
// main.wasp
action scheduleEmailSummary {
fn: import { scheduleSummaryEmail } from "@src/matches/operations",
entities: [Match]
}
job sendEmailSummaryJob {
executor: PgBoss,
perform: {
fn: import { sendEmailSummary } from "@src/workers/schedule",
},
entities: [Match]
}
Сам код отправки письма простой и понятный:
// schedule.ts
export const sendEmailSummary = async ({ email }, context) => {
const matches = await context.entities.Match.findMany(/* query */);
const { textContent, htmlContent } = generateMatchSummary(matches);
await emailSender.send({ to: email, text: textContent, html: htmlContent });
};
А вот как вы назначаете время выполнения задачи:
// operations.ts
export const scheduleEmailSummary = async (_, context) => {
const sendAt = new Date('2025-06-01T08:00:00Z').toISOString();
await sendEmailSummaryJob.delay(sendAt).submit({ email: context.user.email });
};
🎉 Всё! Задача запланирована!
🔁 Повторяющиеся задачи (CRON jobs)
Теперь рассмотрим, как легко настроить ежедневные рассылки:
// main.wasp
job dailyEmailSummary {
executor: PgBoss,
perform: {
fn: import { sendDailySummary } from "@src/workers/cron",
},
schedule: { cron: "0 8 * * *" }, // ежедневно в 8 утра
entities: [Match]
}
И код, который будет выполняться каждый день:
// cron.ts
export const sendDailySummary = async (_, context) => {
const users = await context.entities.User.findMany({ /* условие */ });
const matches = await context.entities.Match.findMany({ /* за вчера */ });
const { textContent, htmlContent } = generateMatchSummary(matches);
for (const user of users) {
await emailSender.send({ to: user.email, text: textContent, html: htmlContent });
}
};
🧙♂️ Магия планирования без сложностей!
📌 Почему это удобно?
Используя PostgreSQL, PgBoss и Wasp, вы получаете:
- 🌿 Минимальную сложность инфраструктуры: не нужны отдельные сервисы.
- ⚡️ Высокую скорость разработки: декларативные конфигурации и встроенные инструменты.
- 🧹 Лёгкость поддержки: меньше кода, меньше ошибок, проще сопровождать.
Это идеальное решение, если вам нужен простой и надёжный планировщик задач.
🧐 Личное мнение автора
Я считаю, что подход Wasp + PgBoss — это отличный пример простоты и функциональности, особенно когда разработчик ценит время и ресурсы. Конечно, в случае интенсивных задач и больших объёмов данных стоит рассматривать более мощные инструменты. Но для небольших и средних проектов такая простота действительно заслуживает внимания.
Это тот случай, когда новая технология реально решает задачу проще и эффективнее, чем старые проверенные методы. Если вы ещё не пробовали — самое время попробовать!
🔗 Полезные ссылки и ресурсы:
Время перестать усложнять и начать использовать простые решения. Попробуйте — вам понравится!