Files
mesh-delivery/modules/mesh-delivery-view/internal/view/read.go
T
jschoubben 6c2b79acf1
mesh/merge-gate head 6c2b79acf106 merged into trunk d68d7ef3d9af — fail: builds mesh-delivery-view → shanks; no bus step; a manifest the change touches fai…
mesh/repo-check head 6c2b79acf106 merged into trunk d68d7ef3d9af — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
Serve the indexer's read tools from the view, not the indexer (ADR 0437 4): indexer_module and indexer_modules read mesh-delivery-indexer.modules through the view's reads. Side effect: carrying the view's tools gives the tool runner read access to every bucket the view reads. (issue 1562)
2026-10-21 13:24:10 +02:00

83 lines
2.3 KiB
Go

package view
// The read tools of the indexer's modules (novox/hq issue 1562): what the indexer stored under modules.<m>, answered as
// stored. The new-form fingerprint (FP2, None2, Inputs2), the reason it has none, and the path and toolchains it was computed
// with are only there. The view reads the bucket through its reads; the reads write nothing.
import (
"encoding/json"
"fmt"
"sort"
"strings"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// The read tools, named as the module is: indexer_ and the verb.
const (
ModuleReadTool = "indexer_module"
ModulesReadTool = "indexer_modules"
)
// StateRead reads the indexer's modules state, as the view's reads grant it: its keys and a key's stored value (nil for a key with none).
type StateRead struct {
Keys func() ([]string, error)
Get func(key string) (json.RawMessage, error)
}
// Reader answers the read tools from a modules state.
type Reader struct{ State StateRead }
// Module is the stored value of modules.<module>, exactly as the indexer wrote it.
func (r Reader) Module(module string) (json.RawMessage, error) {
module = strings.TrimSpace(module)
key, err := delivery.ModulesKey(module)
if err != nil {
return nil, err
}
if r.State.Get == nil {
return nil, fmt.Errorf("the modules state cannot be read here")
}
raw, err := r.State.Get(key)
if err != nil {
return nil, err
}
if len(raw) == 0 {
return nil, fmt.Errorf("no module %s in the modules state", module)
}
return raw, nil
}
// Modules is every key of the modules state with its stored value; with none2 only the modules that have no new-form
// fingerprint and say why (a None2 reason), which is what the fingerprint's check reads live.
func (r Reader) Modules(none2 bool) (map[string]json.RawMessage, error) {
if r.State.Keys == nil || r.State.Get == nil {
return nil, fmt.Errorf("the modules state cannot be read here")
}
keys, err := r.State.Keys()
if err != nil {
return nil, err
}
sort.Strings(keys)
out := map[string]json.RawMessage{}
for _, k := range keys {
raw, err := r.State.Get(k)
if err != nil {
return nil, err
}
if len(raw) == 0 {
continue
}
if none2 {
var m struct {
None2 string `json:"none2"`
}
if json.Unmarshal(raw, &m) != nil || m.None2 == "" {
continue
}
}
out[k] = raw
}
return out, nil
}