convex-cron-jobs은(는) 무엇을 하나요?
백그라운드 작업을 위한 예약 함수 패턴: 간격 스케줄링, 크론 표현식, 작업 모니터링, 재시도 전략 및 장기 실행 작업 모범 사례
소개
Convex는 cronJobs 모듈을 통해 예약 함수를 지원합니다. 이 스킬은 이 기능을 효과적으로 활용하기 위한 패턴과 모범 사례를 제공합니다.
주요 기능
- 간격 스케줄링: 정해진 시간 간격으로 작업 실행
- 크론 표현식:
cron패턴을 사용한 유연한 스케줄링 - 작업 모니터링: 예약된 작업의 상태와 실행 이력 추적
- 재시도 전략: 실패한 작업에 대한 자동 재시도 메커니즘
- 장기 실행 작업: 오래 걸리는 작업을 조각내어 안전하게 처리
사용법
기본 예약 함수
import { cronJobs } from "convex/server";
import { internal } from "./_generated/api";
const crons = cronJobs();
crons.interval("clear-uploaded-files", { hours: 4 }, internal.tasks.clearUploadedFiles);
export default crons;
크론 표현식 사용
crons.cron("weekly-report", "0 0 * * 0", internal.tasks.generateReport);
장기 실행 작업 패턴
작업이 Convex의 시간 제한을 초과할 수 있는 경우, 상태 기반 배치 처리 패턴을 사용하세요:
export const processBatch = internalMutation({
handler: async (ctx) => {
const batch = await ctx.db.query("items")
.withIndex("status", (q) => q.eq("status", "pending"))
.take(100);
if (batch.length === 0) return; // 완료
for (const item of batch) {
await processItem(ctx, item);
await ctx.db.patch(item._id, { status: "processed" });
}
await ctx.scheduler.runAfter(0, internal.tasks.processBatch);
},
});
crons.interval("batch-process", { minutes: 1 }, internal.tasks.processBatch);
재시도 전략
export const sendEmail = internalMutation({
handler: async (ctx, args) => {
try {
await emailService.send(args.to, args.content);
} catch (error) {
const retries = await ctx.db.query("retries")
.withIndex("taskId", (q) => q.eq("taskId", args.taskId))
.collect();
if (retries.length < 3) {
await ctx.db.insert("retries", {
taskId: args.taskId,
at: Date.now() + 60000 * Math.pow(2, retries.length), // 지수 백오프
});
await ctx.scheduler.runAfter(
60000 * Math.pow(2, retries.length),
internal.tasks.sendEmail,
args
);
} else {
console.error("이메일 전송 실패 (최대 재시도 초과)", args.taskId);
}
}
},
});
모니터링
예약 함수의 상태를 모니터링하려면 Convex 대시보드의 cron jobs 섹션을 확인하세요. 각 작업의 마지막 실행 시간, 다음 실행 시간, 성공/실패 기록을 볼 수 있습니다.
모범 사례
- 작업을 멱등성(IDempotent)으로 설계: 동일한 작업이 여러 번 실행되어도 결과가 동일해야 합니다.
- 에러 처리: 모든 예약 함수에서 적절한 try-catch 블록을 사용하세요.
- 시간 초과 고려: 장기 실행 작업은 상태 기반 배치 패턴을 사용하세요.
- 스케줄링 겹침 방지: 이전 실행이 완료되기 전에 새 실행이 시작되지 않도록 해야 합니다.
- 환경별 구성: 개발, 스테이징, 프로덕션 환경에 따라 스케줄을 다르게 설정하세요.