Skip to content

Commit c919694

Browse files
committed
chore(rivetkit): document sleep sequence better
1 parent 30b896a commit c919694

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

rivetkit-typescript/packages/rivetkit/src/actor/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,6 @@ export class ActorContext<
163163
* @experimental
164164
*/
165165
sleep() {
166-
this.#actor._sleep();
166+
this.#actor._startSleep();
167167
}
168168
}

rivetkit-typescript/packages/rivetkit/src/actor/instance.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
150150
#stopCalled = false;
151151

152152
get isStopping() {
153-
return this.#stopCalled || this.#sleepCalled;
153+
return this.#stopCalled;
154154
}
155155

156156
#persistChanged = false;
@@ -1294,8 +1294,6 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
12941294

12951295
#assertReady(allowStoppingState: boolean = false) {
12961296
if (!this.#ready) throw new errors.InternalError("Actor not ready");
1297-
if (!allowStoppingState && this.#sleepCalled)
1298-
throw new errors.InternalError("Actor is going to sleep");
12991297
if (!allowStoppingState && this.#stopCalled)
13001298
throw new errors.InternalError("Actor is stopping");
13011299
}
@@ -1930,7 +1928,7 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
19301928

19311929
if (canSleep) {
19321930
this.#sleepTimeout = setTimeout(() => {
1933-
this._sleep();
1931+
this._startSleep();
19341932
}, this.#config.options.sleepTimeout);
19351933
}
19361934
}
@@ -1958,21 +1956,33 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
19581956
return true;
19591957
}
19601958

1961-
/** Puts an actor to sleep. This should just start the sleep sequence, most shutdown logic should be in _stop (which is called by the ActorDriver when sleeping). */
1962-
_sleep() {
1959+
/**
1960+
* Puts an actor to sleep. This should just start the sleep sequence, most shutdown logic should be in _stop (which is called by the ActorDriver when sleeping).
1961+
*
1962+
* For the engine, this will:
1963+
* 1. Publish EventActorIntent with ActorIntentSleep (via driver.startSleep)
1964+
* 2. Engine runner will wait for CommandStopActor
1965+
* 3. Engine runner will call _onStop and wait for it to finish
1966+
* 4. Engine runner will publish EventActorStateUpdate with ActorStateSTop
1967+
**/
1968+
_startSleep() {
1969+
// IMPORTANT: #sleepCalled should have no effect on the actor's
1970+
// behavior aside from preventing calling _startSleep twice. Wait for
1971+
// `_onStop` before putting in a stopping state.
1972+
if (this.#sleepCalled) {
1973+
this.#rLog.warn({ msg: "already sleeping actor" });
1974+
return;
1975+
}
1976+
this.#sleepCalled = true;
1977+
1978+
// NOTE: Publishes ActorIntentSleep
19631979
const sleep = this.#actorDriver.startSleep?.bind(
19641980
this.#actorDriver,
19651981
this.#actorId,
19661982
);
19671983
invariant(this.#sleepingSupported, "sleeping not supported");
19681984
invariant(sleep, "no sleep on driver");
19691985

1970-
if (this.#sleepCalled) {
1971-
this.#rLog.warn({ msg: "already sleeping actor" });
1972-
return;
1973-
}
1974-
this.#sleepCalled = true;
1975-
19761986
this.#rLog.info({ msg: "actor sleeping" });
19771987

19781988
// Schedule sleep to happen on the next tick. This allows for any action that calls _sleep to complete.
@@ -1985,7 +1995,13 @@ export class ActorInstance<S, CP, CS, V, I, DB extends AnyDatabaseProvider> {
19851995
}
19861996

19871997
// MARK: Stop
1988-
async _stop() {
1998+
/**
1999+
* For the engine:
2000+
* 1. Engine runner receives CommandStopActor
2001+
* 2. Engine runner calls _onStop and waits for it to finish
2002+
* 3. Engine runner publishes EventActorStateUpdate with ActorStateSTop
2003+
*/
2004+
async _onStop() {
19892005
if (this.#stopCalled) {
19902006
this.#rLog.warn({ msg: "already stopping actor" });
19912007
return;

rivetkit-typescript/packages/rivetkit/src/drivers/engine/actor-driver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ export class EngineActorDriver implements ActorDriver {
427427

428428
const handler = this.#actors.get(actorId);
429429
if (handler?.actor) {
430-
await handler.actor._stop();
430+
await handler.actor._onStop();
431431
this.#actors.delete(actorId);
432432
}
433433

rivetkit-typescript/packages/rivetkit/src/drivers/file-system/global-state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ export class FileSystemGlobalState {
325325

326326
// Stop actor
327327
invariant(actor.actor, "actor should be loaded");
328-
await actor.actor._stop();
328+
await actor.actor._onStop();
329329

330330
// Remove from map after stop is complete
331331
this.#actors.delete(actorId);

0 commit comments

Comments
 (0)