-
Notifications
You must be signed in to change notification settings - Fork 33
Description
Currently the scheduling API is fairly constrained.
We're able to schedule future work via c.schedule.after
and c.schedule.at
. There's not, to the best of my knowledge, a mechanism to either see what work is scheduled, nor to cancel any of the scheduled work. One may want to, for example, schedule a drip email campaign in an actor but allow the user to disable emails at a later time (which means you'd need to clear all the scheduled emails).
There are two parts to this proposal.
List Scheduled Work
Add a list
method to schedule
to list the actions that are currently scheduled to run.
type Events = readonly { eventId: string, timestamp: number, fn: string, args: unknown[] }
const events: Events[] = c.schedule.list()
This could be implemented with the drivers as-is and should be broadly supportable across implementations.
Cancel Scheduled Work
This is more involved. I don't know the shape of rivets infra, so I'm going to come at this from the cloudflare perspective.
Cloudflare implements three alarm APIs:
getAlarm(): number | null
setAlarm(ms: number): void
deleteAlarm(): void
Note: Durable objects only support a single alarm so that seems like the lowest common denominator
To support this feature we'll need to make the following changes to the ActorDriver
interface:
interface ActorDriver {
get context(): unknown;
kvGet(actorId: string, key: KvKey): Promise<KvValue | undefined>;
kvGetBatch(actorId: string, key: KvKey[]): Promise<(KvValue | undefined)[]>;
kvPut(actorId: string, key: KvKey, value: KvValue): Promise<void>;
kvPutBatch(actorId: string, key: [KvKey, KvValue][]): Promise<void>;
kvDelete(actorId: string, key: KvKey): Promise<void>;
kvDeleteBatch(actorId: string, key: KvKey[]): Promise<void>;
+ setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void>;
+ getAlarm(actor: AnyActorInstance): Promise<number | null>;
+ deleteAlarm(actor: AnyActorInstance): Promise<void>
}
This suggestion more or less maps to cloudflare's API exactly, with the exception of being async instead of sync.
As for Schedule
, I think we should make the following changes:
interface Schedule {
// after and at now return their `eventId`
after: (duration: number, fn: string, ...args: unknown[]) => Promise<string>;
at: (timestamp: number, fn: string, ...args: unknown[]) => Promise<string>;
get: (alarmId: string) => Promise<Alarm>;
cancel: (alarmId: string) => Promise<void>;
// Included from the above proposal
list: () => Promise<Alarm[]>;
}
// Like the `ScheduleEvent` interface but public
interface Alarm {
id: string;
createdAt: number; // <-- This is just a nice to have but it would provide a sense of progress
triggersAt: number;
fn: string;
args: unknown[];
}