mesh/delivery merged: source.main moved to novox/mesh-sdk@ff5e00f1f894
mesh/delivery-group group feat/data-items merged: every member is merged
mesh/check pass c28c645ca406 on 5ae69df8ccde | unit 4510 run, 4259 kept, 49 skipped | integration 4589 run, 4361 kept, 51 skipped | over bound: unit, …
The contract (state name, key form, value) is in delivery; buscompose grants the engine its own node's keys of mesh-host_data and each node's disk-load a read of its own node's keys alone, the same way the engine's other states are granted. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
73 lines
2.9 KiB
Go
73 lines
2.9 KiB
Go
package delivery
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// **The data items of each module placed on a node, as its engine composed them** (novox/hq ADR 0577 clauses 1 and 4):
|
|
// the node-engine's state `data` (EngineDataBucket), one key `<node>.<module>` (EngineDataKey) per module placed on the
|
|
// node that declares data items, written by that node's engine alone, when the module's composition changes and only
|
|
// when the value differs, and deleted when the module leaves the node. That node's disk-load watches its node's keys
|
|
// (EngineDataNodeKeys) and measures what they name; it composes nothing itself. Only the contract is here: the state's
|
|
// names, its key and its value; the engine composes the items and disk-load measures them.
|
|
|
|
// EngineDataState, EngineDataBucket and EngineDataRead are the node-engine's state data, by its local name, as the bus
|
|
// names it and as a reader declares it.
|
|
const (
|
|
EngineDataState = "data"
|
|
EngineDataBucket = "mesh-host_" + EngineDataState
|
|
EngineDataRead = "mesh-host." + EngineDataState
|
|
)
|
|
|
|
// EngineDataVersion is the version of EngineData's layout.
|
|
const EngineDataVersion = 1
|
|
|
|
// EngineData is one key's value: the module's data items on the node as the engine composed them (each item's id, its
|
|
// path resolved on that node, its measure, class, protection and what covers it), and the digest of the module's
|
|
// composition they came from (ComposedDigestOf).
|
|
type EngineData struct {
|
|
V int `json:"v"`
|
|
Node string `json:"node"`
|
|
Module string `json:"module"`
|
|
Digest string `json:"digest"`
|
|
Items []catalogue.PlacedDataItem `json:"items"`
|
|
}
|
|
|
|
// EngineDataKey is a module's key on a node, `<node>.<module>`, its module part escaped as a have's is (HaveKey).
|
|
func EngineDataKey(node, module string) (string, error) { return HaveKey(node, module) }
|
|
|
|
// EngineDataNodeKeys is the pattern of every key of a node, `<node>.*`: what that node's disk-load watches.
|
|
func EngineDataNodeKeys(node string) (string, error) {
|
|
if err := checkName("node", node); err != nil {
|
|
return "", err
|
|
}
|
|
return node + ".*", nil
|
|
}
|
|
|
|
// EncodeEngineData writes a value at this layout's version.
|
|
func EncodeEngineData(d EngineData) ([]byte, error) {
|
|
d.V = EngineDataVersion
|
|
if _, err := EngineDataKey(d.Node, d.Module); err != nil {
|
|
return nil, err
|
|
}
|
|
if d.Items == nil {
|
|
d.Items = []catalogue.PlacedDataItem{}
|
|
}
|
|
return json.Marshal(d)
|
|
}
|
|
|
|
// DecodeEngineData reads a value; it refuses another version.
|
|
func DecodeEngineData(raw []byte) (EngineData, error) {
|
|
var d EngineData
|
|
if err := json.Unmarshal(raw, &d); err != nil {
|
|
return EngineData{}, fmt.Errorf("delivery: a module's data items are not readable: %w", err)
|
|
}
|
|
if d.V != EngineDataVersion {
|
|
return EngineData{}, fmt.Errorf("delivery: a module's data items of version %d, and this reads %d", d.V, EngineDataVersion)
|
|
}
|
|
return d, nil
|
|
}
|