package buildstep import ( "encoding/json" "fmt" "os" ) // CapacitySetting is the build modules' setting of the node's build capacity (novox/hq ADR 0525 §5, ADR 0567 §12): how // many asks the node takes at once, an integer config value set on each node's layer of mesh-config. No repository names // a node: each build module declares it with the default 0, which pulls nothing, and the controller (or mesh-config) // lays the node's value into the module's settings file. const CapacitySetting = "capacity" // NodeCapacity is the node's build capacity, read from the module's settings file at path at every call, so a change // takes effect at the next pull. No path, no file value, or a value that is not a whole number of at least 0 gives 0 and // a value that cannot be read says why: pulling on a setting nobody can read could build on a node that must not. func NodeCapacity(path, node string, logf func(string, ...any)) func() int { say := func(format string, args ...any) { if logf != nil { logf(format, args...) } } return func() int { if path == "" { return 0 } raw, err := os.ReadFile(path) if err != nil { say("the build capacity cannot be read, so %s pulls nothing: %v", node, err) return 0 } var s map[string]json.RawMessage if err := json.Unmarshal(raw, &s); err != nil { say("the settings file %s is not JSON, so %s pulls nothing: %v", path, node, err) return 0 } n, err := capacityOf(s[CapacitySetting]) if err != nil { say("%v, so %s pulls nothing", err, node) return 0 } return n } } // capacityOf is the capacity a config value holds: absent or null is 0; anything but a whole number of at least 0 is // refused, naming it. func capacityOf(value json.RawMessage) (int, error) { if len(value) == 0 || string(value) == "null" { return 0, nil } var n int if err := json.Unmarshal(value, &n); err != nil || n < 0 { return 0, fmt.Errorf("the build capacity %s is not a whole number of asks at once, 0 or more", value) } return n, nil }