The node-engine serves manifest-reads and says manifest-reads-changed once per link (ADR 0618 §3, §4, issue 774)

Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
This commit is contained in:
2026-11-04 12:38:30 +01:00
parent c93feeb30f
commit 271de0108d
6 changed files with 95 additions and 1 deletions
+32
View File
@@ -87,6 +87,12 @@ type Session struct {
// saying is held while a facts event is noted, so the haves are written in the order the facts are made.
saying sync.Mutex
// reads says whether the engine has said its manifest reads on a link before (novox/hq ADR 0618 §4).
reads struct {
sync.Mutex
linked bool
}
// haves is what this node-engine writes beside its facts (novox/hq ADR 0429 §4, issue 1132).
haves haveState
// healthWritten is this node's health report as last written or read (WriteNodeHealth): the health loop alone
@@ -383,6 +389,32 @@ func (q *Session) RouterRecord(key string) (*stdio.StateEntry, error) {
return asking.RouterRecord(key)
}
// StatedReads is what this engine states it reads of a manifest and when it computed them, which is its start (the
// node seat's verb manifest-reads, novox/hq ADR 0618 §3): the record is written only when it differs, so its put says
// nothing of when an unchanged statement was made.
func (q *Session) StatedReads() ([]string, time.Time) { return manifestReads(), readsStatedAt }
// SayReads says the node seat's event manifest-reads-changed once for the link just opened (novox/hq ADR 0618 §4):
// why "started" on the engine's first link and "returned" on every link after it, so a reader asks the verb again once
// per connection and never once per pass.
func (q *Session) SayReads() {
q.reads.Lock()
why := delivery.ReadsStarted
if q.reads.linked {
why = delivery.ReadsReturned
}
q.reads.linked = true
q.reads.Unlock()
raw, err := delivery.EncodeManifestReadsChanged(delivery.ManifestReadsChanged{Node: q.Membership.Node,
ManifestReads: manifestReads(), At: time.Now().UTC(), Why: why})
if err != nil {
q.init()
q.Say("cannot say the node seat's manifest-reads-changed: " + err.Error())
return
}
q.SayEngine("manifest-reads-changed", json.RawMessage(raw))
}
// SayEngine says one of the node seat's events over the link open now; with none open it is not said.
func (q *Session) SayEngine(event string, body any) {
q.init()