UNPKG

convex

Version:

Client for the Convex Cloud

149 lines (144 loc) 5.22 kB
import { FunctionReference, OptionalRestArgs } from "../server/api.js"; import { Id } from "../values/value.js"; /** * A {@link FunctionReference} that can be scheduled to run in the future. * * Schedulable functions are mutations and actions that are public or internal. * * @public */ export type SchedulableFunctionReference = FunctionReference< "mutation" | "action", "public" | "internal" >; /** * An interface to schedule Convex functions to run in the future. * * Available as `ctx.scheduler` in mutations and actions. * * **Execution guarantees:** * - **Scheduled mutations** are guaranteed to execute **exactly once**. They * are automatically retried on transient errors. * - **Scheduled actions** execute **at most once**. They are not retried and * may fail due to transient errors. * * Consider using an `internalMutation` or `internalAction` to ensure that * scheduled functions cannot be called directly from a client. * * @example * ```typescript * import { mutation } from "./_generated/server"; * import { internal } from "./_generated/api"; * import { v } from "convex/values"; * * export const createOrder = mutation({ * args: { items: v.array(v.string()) }, * returns: v.null(), * handler: async (ctx, args) => { * const orderId = await ctx.db.insert("orders", { items: args.items }); * * // Run immediately after this mutation commits: * await ctx.scheduler.runAfter(0, internal.emails.sendConfirmation, { * orderId, * }); * * // Run cleanup in 7 days: * await ctx.scheduler.runAfter( * 7 * 24 * 60 * 60 * 1000, * internal.orders.archiveOrder, * { orderId }, * ); * * return null; * }, * }); * ``` * * @see https://docs.convex.dev/scheduling/scheduled-functions * @public */ export interface Scheduler { /** * Schedule a function to execute after a delay. * * @example * ```typescript * // Schedule to run as soon as possible (if this is a mutation it would be after this mutation commits): * await ctx.scheduler.runAfter(0, internal.tasks.process, { taskId }); * * // Run after 5 seconds: * await ctx.scheduler.runAfter(5000, internal.tasks.process, { taskId }); * * // Run after 1 hour: * await ctx.scheduler.runAfter(60 * 60 * 1000, internal.cleanup.run, {}); * ``` * * @param delayMs - Delay in milliseconds. Must be non-negative. If the delay * is zero, the scheduled function will be due to execute immediately after the * scheduling one completes. * @param functionReference - A {@link FunctionReference} for the function * to schedule. * @param args - Arguments to call the scheduled functions with. * @returns The ID of the scheduled function in the `_scheduled_functions` * system table. Use this to cancel it later if needed. **/ runAfter<FuncRef extends SchedulableFunctionReference>( delayMs: number, functionReference: FuncRef, ...args: OptionalRestArgs<FuncRef> ): Promise<Id<"_scheduled_functions">>; /** * Schedule a function to execute at a specific time. * * @example * ```typescript * // Run at a specific Date: * await ctx.scheduler.runAt( * new Date("2030-01-01T00:00:00Z"), * internal.events.triggerNewYear, * {}, * ); * * // Run at a timestamp (milliseconds since epoch): * await ctx.scheduler.runAt(Date.now() + 60000, internal.tasks.process, { taskId }); * ``` * * @param timestamp - A Date or a timestamp (milliseconds since the epoch). * If the timestamp is in the past, the scheduled function will be due to * execute immediately after the scheduling one completes. The timestamp can't * be more than five years in the past or more than five years in the future. * @param functionReference - A {@link FunctionReference} for the function * to schedule. * @param args - Arguments to call the scheduled functions with. * @returns The ID of the scheduled function in the `_scheduled_functions` * system table. **/ runAt<FuncRef extends SchedulableFunctionReference>( timestamp: number | Date, functionReference: FuncRef, ...args: OptionalRestArgs<FuncRef> ): Promise<Id<"_scheduled_functions">>; /** * Cancel a previously scheduled function. * * For scheduled **actions**: if the action has not started, it will * not run. If it is already in progress, it will continue running but any * new functions it tries to schedule will be canceled. * If it had already completed, canceling will throw an error. * For scheduled **mutations**: the mutation will either show up as * "pending", "completed", or "failed", but never "inProgress". * Canceling a mutation will atomically cancel it entirely or fail to cancel * if it has committed. It is a transaction that will either run to * completion and commit or fully roll back. * * @example * ```typescript * // Cancel a scheduled function: * await ctx.scheduler.cancel(scheduledFunctionId); * ``` * * @param id - The ID of the scheduled function to cancel (returned by * `runAfter` or `runAt`). */ cancel(id: Id<"_scheduled_functions">): Promise<void>; }