@pgfsm/sync-worker
v0.3.0
Published
fsmlet worker runtime library driving FSM instances for PostgreSQL-backed state machines (ops CLIs live in @pgfsm/ctl)
Readme
@pgfsm/sync-worker
The fsmlet runtime: the out-of-band worker that drives FSM instances forward
by running your actions, guards and delays. The HTTP API never blocks on or owns
worker lifecycle. fsmlet (kubelet — long-running node agent) picks up dispatch
entries that the scheduler (the pg_cron job, SPEC-003) assigns to it.
This package is a library. It ships no CLI bins: a pgfsm project embeds the
worker in its own entry point (sync-worker/typescript/run-sync-worker.ts,
generated by @pgfsm/cli), which
calls runFsmlet with the project's compiled sync-operation registry.
Install
npm install @pgfsm/sync-workerUsage
import { runFsmlet } from "@pgfsm/sync-worker";
import {
FSM_DEFINITIONS,
SYNC_OPERATION_REGISTRATIONS,
} from "./aggregate-generated-sync-operation-registry.ts";
await runFsmlet(
{ connectionString: Deno.env.get("DATABASE_URL") ?? "" },
SYNC_OPERATION_REGISTRATIONS,
FSM_DEFINITIONS, // required: see "Startup check" below
// optional 4th argument: { signal, maxConcurrency, fsmletId, … }
);Startup check
Before it registers, the fsmlet reads fsm_core.fsm_json once and refuses to
start (throwing FsmDefinitionCheckError, which lists every problem) when an
FSM version it serves is:
- missing: not loaded; run
npx @pgfsm/ctl fsm load fsmfirst; - ambiguous: loaded more than once with different content;
- drifted: loaded with different content than the
fsm.jsonthis worker was generated from. A loaded version can't be changed: give the editedfsm.jsona new version; - undigested: missing from
fsmDefinitions; regenerate the sync worker.
The check is mandatory; there's no option to turn it off.
Upgrading from 0.2: runFsmlet/startFsmlet take fsmDefinitions as a
required third argument, before options. Add FSM_DEFINITIONS to the import
from aggregate-generated-sync-operation-registry.ts and pass it as above.
Other exports:
import {
runFsmlet, // long-running node agent
startFsmlet, // same, returning a handle to stop it
startFSMWorker, // drive a single FSM instance
startFSMWorkerWithDBLock, // same, holding a DB-level advisory lock
} from "@pgfsm/sync-worker";
import type {
FsmDefinitionDigest,
FsmletHandle,
FsmletOptions,
SyncOperationRegistration,
} from "@pgfsm/sync-worker";Operating the database: @pgfsm/ctl
@pgfsm/sync-worker ≤ 0.2 also shipped the fsmctl, pgcron and
fsmscheduler bins. They moved to @pgfsm/ctl as
pgfsmctl subcommands (SPEC-005):
| Before (npx -p @pgfsm/sync-worker -- …) | Now (npx @pgfsm/ctl …) |
| ----------------------------------------- | --------------------------------------- |
| pgcron [-s <cron>] | pgcron register [-s <cron>] |
| fsmctl -c create -n <fsm> -V <v> | instance create -n <fsm> -V <v> |
| fsmctl -c resume\|send\|stop -q <id> … | instance resume\|send\|stop -q <id> … |
| fsmscheduler [-p <ms>] [-s <secs>] | scheduler run [-p <ms>] [-s <secs>] |
runFsmScheduler, FsmSchedulerOptions, scheduleNextPending and
SCHEDULER_NOTIFY_CHANNEL moved to @pgfsm/ctl too.
Prerequisites
- A Postgres database with the pgfsm schema applied, the scheduler job
registered once (
npx @pgfsm/ctl pgcron register), and the project's FSM definitions loaded (npx @pgfsm/ctl fsm load fsm, on every deploy)
License
Apache-2.0
