The second half of ADR 0553, merged only once the node-engine that decodes yields runs on every node (§5). The share is the node-engine's own config as the node's layers give it; each step divides it by its own module's capacity. A share out of range bounds builds at the default and never refuses the node's composition. A change of the share recomposes the build runtimes, which restart once.
70 lines
2.1 KiB
Go
70 lines
2.1 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/buildcpu"
|
|
)
|
|
|
|
// yieldsOf is how the runtime of its own a module is served by gives way on this node (novox/hq ADR 0553), or nil when
|
|
// it does not, and the word its steps size their threads from:
|
|
//
|
|
// - a module holding a seat that yields (Seat.Yields, the build seats) runs at idle priority under the node's one share
|
|
// of its processors: the node-engine's own config build-cpu-share (buildcpu.ShareSetting) as this node's layers give
|
|
// it, its default where none does. Every yielding module of the node carries the same share, so the node-engine's
|
|
// one yielding slice has one quota (ADR 0553 §2, §3).
|
|
// - its word: that share (buildcpu.ShareWord), which a step divides by its own module's capacity (ADR 0553 §4).
|
|
//
|
|
// Never a refusal: a share out of range is the default, so a mistyped value bounds the builds at the default and never
|
|
// stops the node's whole composition.
|
|
func (r Resolution) yieldsOf(m Manifest, with Rendering) (map[string]any, map[string]string) {
|
|
if !yields(m) {
|
|
return nil, nil
|
|
}
|
|
engine := Manifest{Module: engineModule}
|
|
for _, e := range r.Modules {
|
|
if e.Module == engineModule {
|
|
engine = e
|
|
}
|
|
}
|
|
share := buildcpu.DefaultPercent
|
|
for _, s := range Effective(engine, with.Settings[engineModule]) {
|
|
if s.Key == buildcpu.ShareSetting {
|
|
if n, ok := percentOf(s.Value); ok {
|
|
share = n
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"priority": "idle", "cpu-share": share},
|
|
map[string]string{buildcpu.ShareWord: strconv.Itoa(share)}
|
|
}
|
|
|
|
// yields is whether a module claims a seat that yields.
|
|
func yields(m Manifest) bool {
|
|
for _, c := range m.Claims {
|
|
if s, ok := SeatNamed(c.Name); ok && s.Yields {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// percentOf is a setting's value as a percent from 1 to 100: a number, or a string holding one.
|
|
func percentOf(v any) (int, bool) {
|
|
var n int
|
|
switch x := v.(type) {
|
|
case float64:
|
|
n = int(x)
|
|
case int:
|
|
n = x
|
|
case string:
|
|
var err error
|
|
if n, err = strconv.Atoi(x); err != nil {
|
|
return 0, false
|
|
}
|
|
default:
|
|
return 0, false
|
|
}
|
|
return n, n >= 1 && n <= 100
|
|
}
|