Aller au contenu
Français

ActorSystem

Ce contenu n’est pas encore disponible dans votre langue.

Defined in: src/ActorSystem.ts:70

The ActorSystem is the top-level container for actors. It owns the root guardians, the event stream, the scheduler, and the default dispatcher. Create one per logical application.

readonly config: Config

Defined in: src/ActorSystem.ts:112

Full merged configuration in effect for this system.


readonly deadLetterQueue: DeadLetterQueue

Defined in: src/ActorSystem.ts:110

Bounded record of the messages this system could not deliver.

Always present, and capturing nothing unless actor-ts.dead-letters.store says otherwise — so list() on a default system answers “nothing kept”, which is the truth, rather than throwing or being undefined.


readonly deadLetters: ActorRef

Defined in: src/ActorSystem.ts:102


readonly dispatcher: Dispatcher

Defined in: src/ActorSystem.ts:79


readonly eventStream: EventStream

Defined in: src/ActorSystem.ts:81


readonly extensions: Extensions

Defined in: src/ActorSystem.ts:114

Per-system extension registry (serialization, sharding, pubsub, …).


readonly log: Logger

Defined in: src/ActorSystem.ts:82


readonly name: string

Defined in: src/ActorSystem.ts:71


readonly scheduler: Scheduler

Defined in: src/ActorSystem.ts:80


readonly startedAtMs: number

Defined in: src/ActorSystem.ts:78

Wall-clock time this system was created. Stamped first in the constructor, so Date.now() - startedAtMs is the system’s uptime — the one clock that survives a monitoring tool attaching, detaching, or reconnecting halfway through the run.

get cluster(): Option<Cluster>

Defined in: src/ActorSystem.ts:344

The Cluster this system joined, or None if it never did (#833).

Filled in by Cluster.join, so a local-only system stays local — the getter never starts a cluster. Inside an actor prefer this.context.cluster (same Option) or this.cluster (unwrapped, for code that already knows it is clustered).

The Cluster type is imported type-only and the value import is just the extension id, which is why core can hand out a cluster without depending on the cluster layer at runtime — the same split EntityContext uses.

Option<Cluster>


get isTerminated(): boolean

Defined in: src/ActorSystem.ts:667

boolean

actorSelection(path): ActorSelection

Defined in: src/ActorSystem.ts:493

Build an ActorSelection that resolves a path at lookup time. Accepts

  • a fully-qualified URI (“actor-ts://sys/user/foo/bar”)
  • an absolute path (“/user/foo/bar” or “user/foo/bar”) Wildcards are not supported in v1.

string

ActorSelection


awaitQuiescence(timeoutMs?): Promise<boolean>

Defined in: src/ActorSystem.ts:627

Wait until nothing under /user has work left it can dispatch, or until timeoutMs elapses. Resolves true if the tree went quiet, false if the budget ran out first.

“Quiet” is per cell: no turn in flight and no dispatchable message queued. Because a cell is marked busy at tell time — synchronously, by the sender’s turn — a reply that has been sent but not yet run already counts, which is what carries the wait across a ping-pong, a router fan-out or a supervision restart instead of flushing one mailbox once.

Two kinds of mailbox are deliberately not waited on, because neither drains at a rate a shutdown could wait for: one parked by context.throttle(...), and one suspended while its actor’s supervisor decides. Both are treated as quiet, and whatever is still queued in them is dead-lettered by the ordinary teardown.

Only /user is inspected. Framework actors under /system — cluster heartbeats, failure detectors, broker reconnect loops — are never quiet by design, so including them would spend the whole budget on every shutdown.

Work that is not in a mailbox yet is not waited for either: a scheduled tick, or a tell from a promise the handler did not await, can still arrive after this resolves.

number = ...

Promise<boolean>


extension<T>(id): T

Defined in: src/ActorSystem.ts:327

Convenience shortcut for system.extensions.get(id) — the one-liner used throughout the codebase to resolve an extension by its id.

T extends Extension

ExtensionId<T>

T


http(port, options?): ServerBuilder

Defined in: src/ActorSystem.ts:365

Shortcut — bind an HTTP server on port (and optionally host) with the framework’s default Fastify backend. Equivalent to:

system.extension(HttpExtensionId)
.newServerAt(host ?? '0.0.0.0', port)
.useBackend(backend ?? new FastifyBackend())

For non-default backends, pass backend: — typically new ExpressBackend(opts) or new HonoBackend(opts). Returns the ServerBuilder so you can chain .bind(routes):

const binding = await system.http(8080).bind(routes);

Note — FastifyBackend is a hard dependency of the framework (not a peer-dep), so the default path needs no extra installs.

number

HttpServerBackend

string

ServerBuilder


runUntilTerminated(signals?): Promise<void>

Defined in: src/ActorSystem.ts:721

Run until the process is asked to stop, then shut down gracefully — the whole of a service’s main after the actors are wired:

const system = ActorSystem.create('orders');
await system.http.bind(routes);
await system.runUntilTerminated();

Installs SIGTERM/SIGINT handlers that start CoordinatedShutdown, resolves once the system is fully down, and detaches the handlers on the way out. That last step is why this exists as a method rather than a documented three-liner: the handlers have to come off in a finally, or a Deno program that shuts down for any other reason — a terminate() from inside, an operator command — never exits, because a Deno.addSignalListener listener holds the event loop open and has no unref.

What replaces the hand-rolled process.on('SIGTERM', () => { … }) is not just the signal plumbing but the ordering. A handler that calls terminate() stops the actors first and only then, if ever, releases the port and leaves the cluster; the pipeline unbinds in service-unbind, closes brokers in service-stop and leaves the cluster in cluster-leave, all before actor-system-terminate — so a rolling deploy takes the node out of rotation while its actors can still finish what they are holding.

Resolves when the pipeline is finished, not merely when the system is down: a task registered alongside the built-in terminator in the final phase runs in parallel with it, and returning while one of those is still going would hand back a “shutdown complete” that is not.

The process stays alive for as long as this promise is pending, and that is a guarantee this method makes rather than one it inherits. A signal handler is not a reason for a runtime to keep running: Node’s signal handles are unref’d, so a system with nothing else on the event loop — no bound port, no open socket, every timer unref’d — used to drain its loop the moment it started waiting and exit instead of ever receiving the SIGTERM it had just armed itself for. Bun refs its handles and Deno’s Deno.addSignalListener cannot be unref’d at all, so the same program waited correctly on two runtimes out of three (#549). A keep-alive timer, released in the same finally as the handlers, makes the three agree.

readonly ProcessSignal[]

Which signals to listen for. Defaults to SIGTERM and SIGINT. One the runtime cannot deliver is skipped — Windows has no SIGTERM under any runtime — so this never fails to start over a platform difference. Note that skipping them all does not turn this into a no-op: the promise still waits, and the process still stays alive, until something shuts the system down from inside.

Promise<void>


spawn<T>(actor, name, options?): ActorRef<T>

Defined in: src/ActorSystem.ts:384

Spawn a top-level user actor under /user with a deterministic caller-supplied name. The name must be unique among siblings (i.e. children of /user) — if a child with the same name already exists, the call throws.

For an auto-generated name, see spawnAnonymous.

system.spawn(Greeter, 'greeter'); // zero-arg class
system.spawn(() => new Worker(database), 'worker'); // dependencies

T

ActorClassOrFactory<T>

string

ActorOptions<T>

ActorRef<T>


spawnAnonymous<T>(actor, options?): ActorRef<T>

Defined in: src/ActorSystem.ts:397

Spawn a top-level user actor under /user with an auto-generated name. Use when the caller doesn’t care about the path — e.g. one-shot async work, throwaway helpers. For a deterministic name, see spawn.

T

ActorClassOrFactory<T>

ActorOptions<T>

ActorRef<T>


spawnTyped<T>(behavior, name): ActorRef<T>

Defined in: src/ActorSystem.ts:412

Spawn a typed Behavior under /user with a deterministic name — the Behavior-DSL counterpart to spawn. Wraps the Behavior in typedActor(behavior) so callers don’t have to thread a factory through the typed API.

const ref = system.spawnTyped(counter(0), 'counter');

T

Behavior<T>

string

ActorRef<T>


spawnTypedAnonymous<T>(behavior): ActorRef<T>

Defined in: src/ActorSystem.ts:421

Anonymous variant of spawnTyped — the Behavior-DSL counterpart to spawnAnonymous. Pick this when the caller doesn’t need a stable path.

T

Behavior<T>

ActorRef<T>


stop(ref): void

Defined in: src/ActorSystem.ts:555

Stop an actor once it has worked through its mailbox — fire and forget.

The same graceful stop ActorRef.stop() performs, and like it this returns nothing: the JSDoc promised a promise for a signature that never had one (#663). Await the stop with gracefulStop(ref, timeoutMs).

ActorRef

void


terminate(): Promise<void>

Defined in: src/ActorSystem.ts:580

Shut down: drains /user, stops it (children first), then /system, and resolves once everything is torn down. The two guardians go in sequence so a user actor’s postStop can still reach the framework actors it depends on — see GUARDIAN_SHUTDOWN_ORDER.

The drain in front is what makes ref.tell(x); await system.terminate() deliver x (#663). It has to be here rather than inside the cascade because a terminate is a system command: ActorCell.run() re-checks its system queue after every await, so a terminate that lands in a running turn’s await window is picked up before the user message queued behind it — and the cell that has flipped to terminating no longer dequeues user messages at all, so the rest went to dead letters. Waiting for quiescence before the first terminate is enqueued is the only ordering that does not fight that, and it leaves the teardown itself exactly as it was.

Bounded by actor-ts.system.shutdown-drain-timeout; set it to 0 to skip the drain entirely. See awaitQuiescence for what “quiet” means and which mailboxes are deliberately not waited on.

Promise<void>


whenTerminated(): Promise<void>

Defined in: src/ActorSystem.ts:660

Promise that resolves when the system has finished shutting down.

Promise<void>


static create(name?, options?): ActorSystem

Defined in: src/ActorSystem.ts:316

Create a new actor system. Omitting name falls back to actor-ts.system.name and, failing that, to "default" — so a deployment can name its system from config without a rebuild.

string

ActorSystemOptions = {}

ActorSystem