Merge pull request 'Module state is hq ADR 0202 (0201 landed first for a provider's derivations)' (#19) from fix/adr-0202-module-state into main
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
This commit is contained in:
@@ -42,7 +42,7 @@ react to mesh events, and the envelope/routing-key conventions. Transport primit
|
||||
`state(name)` reaches a state the module declared it keeps (`state` in its manifest) or reads
|
||||
(`reads`, as `<module>.<name>`): `get`, `put`, `delete`, `keys`, and `watch`, which hands the current
|
||||
values and then every change. Through the runtime that launched the bundle, which refuses what the
|
||||
module did not declare. Current values, never history and never a secret (novox/hq ADR 0201).
|
||||
module did not declare. Current values, never history and never a secret (novox/hq ADR 0202).
|
||||
|
||||
### `primitives` — sealing, semver, resolved-env
|
||||
Seal/unseal for secrets, semantic version comparison, and the accessor a module uses to read its
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
// State — the current value of something a module keeps on the bus, which every machine sees,
|
||||
// including one that joins later (novox/hq ADR 0201). Not history: that is an event. Never a secret,
|
||||
// including one that joins later (novox/hq ADR 0202). Not history: that is an event. Never a secret,
|
||||
// sealed or not. A module declares what it keeps (`state`) and what it reads (`reads`, as
|
||||
// `<module>.<name>`) and names each here as it named it there; the runtime refuses, with the reason,
|
||||
// what it did not declare.
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Go bundle keeps and watches its state through the runtime (novox/hq ADR 0201): the watch's
|
||||
// A Go bundle keeps and watches its state through the runtime (novox/hq ADR 0202): the watch's
|
||||
// current values are handled before it returns, its changes are named by the watch's id, a change for
|
||||
// no watch of this bundle is refused, and put, get and keys are asked of the runtime as the module.
|
||||
func TestABundleKeepsAndWatchesStateThroughTheRuntime(t *testing.T) {
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ type channel struct {
|
||||
next int
|
||||
waiting map[string]chan message
|
||||
listeners []listener
|
||||
// watches are this bundle's state watches by the id each was asked with (ADR 0201).
|
||||
// watches are this bundle's state watches by the id each was asked with (ADR 0202).
|
||||
watches map[string]func(StateChange) error
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ func ServeOn(name string, tools []Tool, in io.Reader, out io.Writer) error {
|
||||
c.say(map[string]any{"id": id, "result": map[string]any{}})
|
||||
}(id, *p.Envelope, matching)
|
||||
case "mesh/state":
|
||||
// One change to a state this bundle watches (ADR 0201), named by the watch's id, answered
|
||||
// One change to a state this bundle watches (ADR 0202), named by the watch's id, answered
|
||||
// once its handler has taken it. Beside the loop, like a tool call.
|
||||
var p struct {
|
||||
Watch string `json:"watch"`
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
// State — the current value of something a module keeps on the bus, which every machine sees,
|
||||
// including one that joins later (novox/hq ADR 0201). Not history: that is an event. Never a secret,
|
||||
// including one that joins later (novox/hq ADR 0202). Not history: that is an event. Never a secret,
|
||||
// sealed or not: a bucket is kept, and a machine joining a year later reads it whole.
|
||||
//
|
||||
// A module declares the state it keeps (`state` in its manifest) and the state of others it reads
|
||||
@@ -65,7 +65,7 @@ function bound(): StateChannel {
|
||||
if (!channel) {
|
||||
throw new Error(
|
||||
"no runtime to keep state through — a module's state is reached through the runtime that launched " +
|
||||
"its bundle (novox/hq ADR 0201)",
|
||||
"its bundle (novox/hq ADR 0202)",
|
||||
);
|
||||
}
|
||||
return channel;
|
||||
|
||||
+2
-2
@@ -71,7 +71,7 @@ function startSession(): Session {
|
||||
});
|
||||
const ask = (method: string, params: unknown): Promise<unknown> => askAs(`bundle-${nextOut++}`, method, params);
|
||||
|
||||
// The module's state (ADR 0201): each watch's changes arrive as `mesh/state` requests naming the
|
||||
// The module's state (ADR 0202): each watch's changes arrive as `mesh/state` requests naming the
|
||||
// watch by the id it was asked with, so its handler is registered under that id before it is asked
|
||||
// — the current values arrive before the watch itself is answered.
|
||||
const watches = new Map<string, (change: StateChange<unknown>) => Promise<void>>();
|
||||
@@ -176,7 +176,7 @@ function startSession(): Session {
|
||||
return;
|
||||
}
|
||||
case "mesh/state": {
|
||||
// One change to a state this bundle watches (ADR 0201), answered once its handler has taken
|
||||
// One change to a state this bundle watches (ADR 0202), answered once its handler has taken
|
||||
// it. The runtime delivers a watch's changes one at a time, in order.
|
||||
const p = request.params as { watch?: string; change?: StateChange<unknown> } | undefined;
|
||||
const deliver = p?.watch !== undefined ? watches.get(String(p.watch)) : undefined;
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
// A launched bundle that keeps state through its runtime (novox/hq ADR 0201): it watches its servers as
|
||||
// A launched bundle that keeps state through its runtime (novox/hq ADR 0202): it watches its servers as
|
||||
// it is imported, before it says what it serves, and its tools write, read and list them.
|
||||
import { state } from "../../dist/state/index.js";
|
||||
import { registerModuleTools } from "../../dist/tools/index.js";
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@ test("a launched bundle subscribes as it is imported, handles events the runtime
|
||||
}
|
||||
});
|
||||
|
||||
test("a launched bundle watches its state as it is imported, has the current values before it goes on, and keeps state through the runtime (ADR 0201)", async () => {
|
||||
test("a launched bundle watches its state as it is imported, has the current values before it goes on, and keeps state through the runtime (ADR 0202)", async () => {
|
||||
const child = spawn(process.execPath, [fileURLToPath(new URL("./fixtures/stdio-state.mjs", import.meta.url))],
|
||||
{ stdio: ["pipe", "pipe", "pipe"], env: { ...process.env, MESH_SERVED_MODULE: "keeper" } });
|
||||
const seen: any[] = [];
|
||||
|
||||
Reference in New Issue
Block a user