feat(tasks): expose req and waitUntil in context#4037
Conversation
|
@RihanArfan is attempting to deploy a commit to the Nitro Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThis PR updates the task scheduling system across multiple runtime presets to propagate a Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/runtime/internal/task.ts (1)
63-65:⚠️ Potential issue | 🟡 Minor
scheduledTimecaptures server startup time, not the cron fire time
payloadis created once whenstartScheduleRunneris called, so every cron invocation shares the samescheduledTime— the server start time. Move the payload construction inside the cron callback so each invocation records the actual scheduled time.🐛 Proposed fix
- const payload: TaskPayload = { - scheduledTime: Date.now(), - }; - for (const schedule of scheduledTasks) { new Cron(schedule.cron, async () => { + const payload: TaskPayload = { + scheduledTime: Date.now(), + }; await Promise.all(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/runtime/internal/task.ts` around lines 63 - 65, The payload object (TaskPayload) is being created once when startScheduleRunner is called so scheduledTime captures server startup time; to fix, move the construction of const payload: TaskPayload = { scheduledTime: Date.now() } into the cron callback inside startScheduleRunner (i.e., build a fresh payload for each cron invocation) so each run sets scheduledTime at invocation time and use that per-task payload when calling the task handler.
🧹 Nitpick comments (1)
src/runtime/internal/task.ts (1)
68-79:waitUntilis only passed to task context — the cron callback never registers itself with the server lifecycleThe schedule runner passes
waitUntilinto task context (so tasks may opt in), but the cron callback itself never callswaitUntil(tasksPromise). In runtimes with graceful-shutdown semantics (e.g., Cloudflare-style), scheduled tasks can be interrupted if the server receives a shutdown signal, because nothing registers the in-progress work at the server level. Consider forwarding the aggregate promise:♻️ Suggested approach
new Cron(schedule.cron, async () => { - await Promise.all( - schedule.tasks.map((name) => - runTask(name, { - payload, - context: { waitUntil }, - }).catch((error) => { - console.error(`Error while running scheduled task "${name}"`, error); - }) - ) - ); + const tasksPromise = Promise.all( + schedule.tasks.map((name) => + runTask(name, { + payload, + context: { waitUntil }, + }).catch((error) => { + console.error(`Error while running scheduled task "${name}"`, error); + }) + ) + ); + waitUntil?.(tasksPromise); + await tasksPromise; });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/runtime/internal/task.ts` around lines 68 - 79, The cron callback starts all scheduled runTask calls but never registers the aggregate work with the lifecycle, so ongoing tasks can be terminated on shutdown; capture the Promise.all result (e.g., tasksPromise = Promise.all(...)) and call waitUntil(tasksPromise) from inside the Cron callback so the runtime knows about the in-flight work; keep the existing per-task .catch logging but ensure you pass the wrapped/aggregated promise to waitUntil after mapping schedule.tasks to runTask(name, { payload, context: { waitUntil } }) so the Cron lifecycle is properly awaited.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/runtime/internal/task.ts`:
- Around line 54-58: Update the TaskContext type to include an optional
waitUntil property with signature waitUntil?: (promise: Promise<unknown>) =>
void (modify the TaskContext interface in src/types/runtime/task.ts) and add
JSDoc to the startScheduleRunner function's options parameter documenting the
options object and the waitUntil callback behavior; ensure the
startScheduleRunner signature and any place that constructs TaskContext (where {
waitUntil } is passed) remain type-safe with the new optional property name
TaskContext.waitUntil.
---
Outside diff comments:
In `@src/runtime/internal/task.ts`:
- Around line 63-65: The payload object (TaskPayload) is being created once when
startScheduleRunner is called so scheduledTime captures server startup time; to
fix, move the construction of const payload: TaskPayload = { scheduledTime:
Date.now() } into the cron callback inside startScheduleRunner (i.e., build a
fresh payload for each cron invocation) so each run sets scheduledTime at
invocation time and use that per-task payload when calling the task handler.
---
Nitpick comments:
In `@src/runtime/internal/task.ts`:
- Around line 68-79: The cron callback starts all scheduled runTask calls but
never registers the aggregate work with the lifecycle, so ongoing tasks can be
terminated on shutdown; capture the Promise.all result (e.g., tasksPromise =
Promise.all(...)) and call waitUntil(tasksPromise) from inside the Cron callback
so the runtime knows about the in-flight work; keep the existing per-task .catch
logging but ensure you pass the wrapped/aggregated promise to waitUntil after
mapping schedule.tasks to runTask(name, { payload, context: { waitUntil } }) so
the Cron lifecycle is properly awaited.
🔗 Linked issue
❓ Type of change
📚 Description
📝 Checklist
TODO
server.waitUntilh3js/srvx#183