Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Commit 026ce04

Browse files
committed
Implement alarm methods for other drivers
1 parent 2d2a9d0 commit 026ce04

File tree

4 files changed

+73
-5
lines changed

4 files changed

+73
-5
lines changed

packages/actor-core/src/test/driver/actor.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type ActorDriverContext = Record<never, never>;
1010

1111
export class TestActorDriver implements ActorDriver {
1212
#state: TestGlobalState;
13+
#alarms: Map<string, { timeout: NodeJS.Timeout; timestamp: number }> = new Map();
1314

1415
constructor(state: TestGlobalState) {
1516
this.#state = state;
@@ -67,9 +68,30 @@ export class TestActorDriver implements ActorDriver {
6768
}
6869

6970
async setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void> {
70-
setTimeout(() => {
71+
// Clear any existing alarm for this actor
72+
await this.deleteAlarm(actor);
73+
74+
const expires = Math.max(timestamp - Date.now(), 0);
75+
// Set new alarm
76+
const timeout = setTimeout(() => {
7177
actor.onAlarm();
72-
}, timestamp - Date.now());
78+
this.#alarms.delete(actor.id);
79+
}, expires);
80+
81+
this.#alarms.set(actor.id, { timeout, timestamp });
82+
}
83+
84+
async getAlarm(actor: AnyActorInstance): Promise<number | null> {
85+
const alarm = this.#alarms.get(actor.id);
86+
return alarm ? alarm.timestamp : null;
87+
}
88+
89+
async deleteAlarm(actor: AnyActorInstance): Promise<void> {
90+
const alarm = this.#alarms.get(actor.id);
91+
if (alarm) {
92+
clearTimeout(alarm.timeout);
93+
this.#alarms.delete(actor.id);
94+
}
7395
}
7496

7597
// Simple key serialization without depending on keys.ts

packages/drivers/memory/src/actor.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export type ActorDriverContext = Record<never, never>;
55

66
export class MemoryActorDriver implements ActorDriver {
77
#state: MemoryGlobalState;
8+
#alarms = new Map<string, { timeout: NodeJS.Timeout; timestamp: number }>();
89

910
constructor(state: MemoryGlobalState) {
1011
this.#state = state;
@@ -62,9 +63,29 @@ export class MemoryActorDriver implements ActorDriver {
6263
}
6364

6465
async setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void> {
65-
setTimeout(() => {
66+
// Clear any existing alarm
67+
await this.deleteAlarm(actor);
68+
69+
// Set new alarm
70+
const timeout = setTimeout(() => {
6671
actor.onAlarm();
72+
this.#alarms.delete(actor.id);
6773
}, timestamp - Date.now());
74+
75+
this.#alarms.set(actor.id, { timeout, timestamp });
76+
}
77+
78+
async getAlarm(actor: AnyActorInstance): Promise<number | null> {
79+
const alarm = this.#alarms.get(actor.id);
80+
return alarm?.timestamp ?? null;
81+
}
82+
83+
async deleteAlarm(actor: AnyActorInstance): Promise<void> {
84+
const alarm = this.#alarms.get(actor.id);
85+
if (alarm) {
86+
clearTimeout(alarm.timeout);
87+
this.#alarms.delete(actor.id);
88+
}
6889
}
6990

7091
// Simple key serialization without depending on keys.ts

packages/platforms/cloudflare-workers/src/actor_driver.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {
1+
import type {
22
ActorDriver,
33
KvKey,
44
KvValue,
@@ -91,6 +91,14 @@ export class CloudflareWorkersActorDriver implements ActorDriver {
9191
await this.#getDOCtx(actor.id).storage.setAlarm(timestamp);
9292
}
9393

94+
async getAlarm(actor: AnyActorInstance): Promise<number | null> {
95+
return this.#getDOCtx(actor.id).storage.getAlarm();
96+
}
97+
98+
async deleteAlarm(actor: AnyActorInstance): Promise<void> {
99+
await this.#getDOCtx(actor.id).storage.deleteAlarm();
100+
}
101+
94102
#serializeKey(key: KvKey): string {
95103
return JSON.stringify(key);
96104
}

packages/platforms/rivet/src/actor_driver.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface ActorDriverContext {
77

88
export class RivetActorDriver implements ActorDriver {
99
#ctx: ActorContext;
10+
#alarm: { timeout: ReturnType<typeof setTimeout>; timestamp: number } | null = null;
1011

1112
constructor(ctx: ActorContext) {
1213
this.#ctx = ctx;
@@ -48,9 +49,25 @@ export class RivetActorDriver implements ActorDriver {
4849
}
4950

5051
async setAlarm(actor: AnyActorInstance, timestamp: number): Promise<void> {
52+
await this.deleteAlarm(actor);
53+
5154
const timeout = Math.max(0, timestamp - Date.now());
52-
setTimeout(() => {
55+
const timeoutId = setTimeout(() => {
5356
actor.onAlarm();
57+
this.#alarm = null;
5458
}, timeout);
59+
60+
this.#alarm = { timeout: timeoutId, timestamp };
61+
}
62+
63+
async getAlarm(_actor: AnyActorInstance): Promise<number | null> {
64+
return this.#alarm?.timestamp ?? null;
65+
}
66+
67+
async deleteAlarm(_actor: AnyActorInstance): Promise<void> {
68+
if (this.#alarm) {
69+
clearTimeout(this.#alarm.timeout);
70+
this.#alarm = null;
71+
}
5572
}
5673
}

0 commit comments

Comments
 (0)