feat(tasks): implement long-term delayed tasks with KV and Cron

This commit is contained in:
2025-11-29 09:03:21 -05:00
parent 40fa0080b5
commit 24d507a48f
8 changed files with 769 additions and 0 deletions

View File

@@ -39,6 +39,41 @@ export async function queueTask(
body,
req?.header(),
);
const MAX_DELAY_SECONDS = 12 * 60 * 60; // 43,200 seconds (12 hours)
// If delay exceeds 12 hours, store in KV for later processing
if (scheduleTime > MAX_DELAY_SECONDS) {
if (!env || !env.DELAYED_TASKS) {
throw new Error("DELAYED_TASKS KV namespace not available");
}
const { generateTaskKey, serializeDelayedTask } = await import(
"./delayedTask"
);
const taskId = crypto.randomUUID();
const scheduledEpochTime = Math.floor(Date.now() / 1000) + scheduleTime;
const metadata = {
queueName,
body,
headers,
scheduledEpochTime,
taskId,
createdAt: Math.floor(Date.now() / 1000),
retryCount: 0,
};
const key = generateTaskKey(scheduledEpochTime, taskId);
await env.DELAYED_TASKS.put(key, serializeDelayedTask(metadata));
console.log(
`Task stored in KV for delayed execution. Scheduled for: ${new Date(scheduledEpochTime * 1000).toISOString()}, Key: ${key}`,
);
return;
}
// Otherwise, queue directly
const contentType =
headers["Content-Type"] === "application/json" ? "json" : "text";
if (!env) {
@@ -85,10 +120,12 @@ function buildTask(
if (scheduleConfig) {
const { delay, epochTime } = scheduleConfig;
if (epochTime) {
console.log("epochTime", epochTime);
scheduleTime = DateTime.fromSeconds(epochTime)
.diffNow("second")
.as("second");
} else if (delay) {
console.log("delay", delay);
scheduleTime = Duration.fromDurationLike(delay).as("second");
}
}