Serve a module's log verbs so its record outlives a bucket's cap and the events' week (ADR 0297, issues 501, 502)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds mesh-tools, node-tools → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of …
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…

The runtime answers mesh/log.append, read, last and info for a log issued
in the module's membership, by publish, batch direct get and stream info
alone. A stale expect is refused as a lost state update, so a module tells
it by the same code.
This commit is contained in:
jochen
2026-10-11 19:18:46 +02:00
parent 336a2b1328
commit d535dd5322
8 changed files with 776 additions and 2 deletions
+55
View File
@@ -670,6 +670,61 @@ func (b *moduleBus) State(verb string, params json.RawMessage) (json.RawMessage,
return json.Marshal(answer)
}
// logAsked is what a bundle names when it reaches its log (novox/hq ADR 0297).
type logAsked struct {
Log string `json:"log"`
Key string `json:"key"`
Value json.RawMessage `json:"value"`
Expect *uint64 `json:"expect"`
From uint64 `json:"from"`
Keys string `json:"keys"`
Limit int `json:"limit"`
}
// Log answers a bundle's `append`, `read`, `last` and `info` on its module's log (ADR 0297). The runtime
// refuses, with the reason, a log the module was not issued; an append whose `expect` is stale is
// refused with the code of a lost state update.
func (b *moduleBus) Log(verb string, params json.RawMessage) (json.RawMessage, error) {
var asked logAsked
if err := json.Unmarshal(params, &asked); err != nil || asked.Log == "" {
return nil, fmt.Errorf("mesh/log.%s names no log: {log, ...}", verb)
}
conn := b.all.conn
var answer any
switch verb {
case "append":
seq, err := conn.LogAppend(b.module, asked.Log, asked.Key, asked.Value, asked.Expect)
if err != nil {
return nil, err
}
answer = map[string]any{"sequence": seq}
case "read":
page, err := conn.LogRead(b.module, asked.Log, asked.From, asked.Keys, asked.Limit)
if err != nil {
return nil, err
}
answer = page
case "last":
entry, err := conn.LogLast(b.module, asked.Log, asked.Key)
if err != nil {
return nil, err
}
if entry == nil {
return json.RawMessage("null"), nil
}
answer = entry
case "info":
info, err := conn.LogInfo(b.module, asked.Log)
if err != nil {
return nil, err
}
answer = info
default:
return nil, fmt.Errorf("the runtime answers no mesh/log.%s", verb)
}
return json.Marshal(answer)
}
// Watch hands a bundle its module's state as it is and as it changes (ADR 0201): `{state, key}`, the
// key a pattern with `*` and `**`, empty for every key.
func (b *moduleBus) Watch(params json.RawMessage, deliver func(json.RawMessage) error) (func(), error) {