Files
mesh-delivery/modules/mesh-delivery-view/internal/view/difference.go
T
jschoubben 316af50da3 VW3: the view's tiers are the assigner's difference of a source revision's kept revision
view_tiers compares the kept assignment revision whose catalog carries the source revision with the one kept before it,
through the seat mesh-wants' verbs revision and difference (view/difference.go, tiers.go Tiers), and reads the tiers and each
module's after (module and edge kind) from the answer; the view orders nothing. The manifest invokes the two verbs.

Builds: design 47 G §512, §186, A-242
2026-11-12 09:15:40 +01:00

94 lines
3.3 KiB
Go

package view
import (
"encoding/json"
"fmt"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/meshwants"
"git.novox.be/novox/mesh-sdk/go/buscalls"
)
// The seat mesh-wants' verbs revision and difference as the view's invokes names them: the tiers of a source revision are
// read through them and worked out nowhere in the view (design 47 G §512, §186, A-242).
const (
RevisionVerb = "seat:" + meshwants.Seat + "." + meshwants.VerbRevision
DifferenceVerb = "seat:" + meshwants.Seat + "." + meshwants.VerbDifference
)
// WalkMost is the most kept assignment revisions a source revision's revision is looked for through, newest first.
const WalkMost = 256
// callSeat asks verb with body through call and reads its declared answer into out.
func callSeat(call func(key string, body any) (json.RawMessage, error), verb string, body, out any) error {
raw, err := call(verb, body)
if err != nil {
return fmt.Errorf("%s: %w", verb, err)
}
answer, said, ok := buscalls.Unwrap(raw)
if !ok {
return fmt.Errorf("%s answered: %s", verb, said)
}
if err := json.Unmarshal(answer, out); err != nil {
return fmt.Errorf("the answer of %s does not read: %w", verb, err)
}
return nil
}
// AssignmentOf asks the seat for one kept assignment graph revision (0: the trunk's newest).
func AssignmentOf(call func(key string, body any) (json.RawMessage, error)) func(revision int64) (meshwants.AssignmentRevision, error) {
return func(revision int64) (meshwants.AssignmentRevision, error) {
var a meshwants.RevisionAnswer
err := callSeat(call, RevisionVerb, meshwants.RevisionInput{Revision: revision}, &a)
return a.Revision, err
}
}
// DifferenceOf asks the seat for the difference of two kept revisions.
func DifferenceOf(call func(key string, body any) (json.RawMessage, error)) func(from, to int64) (meshwants.Difference, error) {
return func(from, to int64) (meshwants.Difference, error) {
var d meshwants.Difference
err := callSeat(call, DifferenceVerb, meshwants.DifferenceInput{From: from, To: to}, &d)
return d, err
}
}
// revisionsOf finds the kept assignment revisions that carry the source revision for a watched branch: to the first of them
// (the one whose change it is) and from the revision kept before it, walking back from the newest. A zero from says there is
// none before it.
func (r Reader) revisionsOf(source uint64) (from, to int64, err error) {
if r.Assignment == nil || r.Difference == nil {
return 0, 0, fmt.Errorf("the assigner's revisions cannot be read here")
}
newest, err := r.Assignment(0)
if err != nil {
return 0, 0, fmt.Errorf("the assigner's newest revision: %w", err)
}
carries := func(rev meshwants.AssignmentRevision) bool {
for _, c := range rev.Catalogs {
if c.Source > 0 && uint64(c.Source) == source {
return true
}
}
return false
}
for n, steps := newest.Revision, 0; n >= 1 && steps < WalkMost; n, steps = n-1, steps+1 {
rev := newest
if n != newest.Revision {
if rev, err = r.Assignment(n); err != nil {
continue // a revision no longer kept
}
}
if !carries(rev) {
if to != 0 {
return rev.Revision, to, nil // the kept revision before the first that carries it
}
continue
}
to = rev.Revision
}
if to == 0 {
return 0, 0, fmt.Errorf("no kept assignment revision of the assigner carries the source revision %d", source)
}
return 0, to, nil
}