80 lines
2.7 KiB
Go
80 lines
2.7 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strconv"
|
|
)
|
|
|
|
// The build processor share's names (novox/hq ADR 0553 §3, §4), written here as well as in the build modules' package
|
|
// (BuildCPUShareSetting, ShareWord, DefaultPercent), so a manifest reader does not reach the build runner's code; a
|
|
// test of the build modules keeps them agreeing.
|
|
const (
|
|
// BuildCPUShareSetting is the node-engine's config value of the node's processor share for its builds, in percent.
|
|
BuildCPUShareSetting = "build-cpu-share"
|
|
// BuildCPUShareWord is the word the composer gives every yielding module: the node's share, in percent.
|
|
BuildCPUShareWord = "MESH_BUILD_CPU_SHARE"
|
|
// BuildCPUDefaultPercent is the share where nothing sets one.
|
|
BuildCPUDefaultPercent = 50
|
|
)
|
|
|
|
// 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 (BuildCPUShareSetting) 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 (BuildCPUShareWord), 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 := BuildCPUDefaultPercent
|
|
for _, s := range Effective(engine, with.Settings[engineModule]) {
|
|
if s.Key == BuildCPUShareSetting {
|
|
if n, ok := percentOf(s.Value); ok {
|
|
share = n
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"priority": "idle", "cpu-share": share},
|
|
map[string]string{BuildCPUShareWord: 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
|
|
}
|