convex-cron-jobs は何をしますか?
バックグラウンドタスクのためのスケジュール関数パターン:インターバルスケジューリング、cron式、ジョブ監視、リトライ戦略、長時間実行タスクのベストプラクティスを提供します。
概要
Convexは、crons.ts ファイルを使用してバックグラウンドタスクをスケジュールするための cronJobs API を提供します。このスキルでは、これらのジョブを効果的に管理するためのパターンについて説明します。
主要な概念
1. インターバルスケジューリング
一定の間隔でジョブを実行します。
// convex/crons.ts
import { cronJobs } from "convex/server";
import { internal } from "./_generated/api";
const crons = cronJobs();
crons.interval("cleanup old data", { hours: 1 }, internal.tasks.cleanup);
export default crons;
2. cron式
特定の時間や日時にジョブを実行します。
crons.cron("daily report", "0 9 * * 1-5", internal.tasks.generateReport);
3. ジョブ監視
convex/schema.ts にジョブの状態を追跡するためのテーブルを定義します。
// convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
jobStatus: defineTable({
jobName: v.string(),
status: v.union(v.literal("running"), v.literal("completed"), v.literal("failed")),
startedAt: v.number(),
completedAt: v.optional(v.number()),
error: v.optional(v.string()),
metadata: v.optional(v.any()),
}).index("by_jobName", ["jobName"]),
});
4. リトライ戦略
ジョブが失敗した場合のリトライメカニズムを実装します。
// convex/tasks.ts
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const processWithRetry = mutation({
args: { jobName: v.string(), maxRetries: v.optional(v.number()) },
handler: async (ctx, args) => {
const maxRetries = args.maxRetries ?? 3;
let retries = 0;
while (retries < maxRetries) {
try {
// 実際のジョブ処理
await performJob(ctx);
break; // 成功したらループを抜ける
} catch (error) {
retries++;
if (retries >= maxRetries) {
throw new Error(`ジョブ ${args.jobName} は最大リトライ回数 ${maxRetries} 回を超えました`);
}
// 指数バックオフ
await ctx.scheduler.runAfter(1000 * Math.pow(2, retries), internal.tasks.retry, {
jobName: args.jobName,
attempt: retries,
});
}
}
},
});
5. 長時間実行タスクのベストプラクティス
- タスクを小さなステップに分割する
- 進捗状況をデータベースに保存する
ctx.scheduler.runAfterを使用してタスクをチェーンする- メモリ制限に注意する
使用例
以下は、1時間ごとに実行される監視ジョブの完全な例です。
// convex/crons.ts
import { cronJobs } from "convex/server";
import { internal } from "./_generated/api";
const crons = cronJobs();
crons.interval("monitor system health", { hours: 1 }, internal.monitoring.checkHealth);
export default crons;
// convex/monitoring.ts
import { mutation } from "./_generated/server";
export const checkHealth = mutation({
handler: async (ctx) => {
const healthStatus = await performHealthCheck();
await ctx.db.insert("jobStatus", {
jobName: "monitor system health",
status: "completed",
startedAt: Date.now(),
completedAt: Date.now(),
metadata: { status: healthStatus },
});
},
});