ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk carries no composition rule. The catalogue functions only the node-engine's composition reaches (Resolve, Resolution's Compose, Declaration, DataItems, LeftOut, Rules and the rest, the settings, placeholder and template refusals, the rendering helpers) are copied with their tests into internal/compose/resolution; a method of a mesh-sdk shape becomes a function taking it first. The composition calls its own copies, and the captured catalogue its tests read lives here now, shared by mesh-compose's tests. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
70 lines
2.2 KiB
Go
70 lines
2.2 KiB
Go
package resolution
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// 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 resolutionYieldsOf(r mcat.Resolution, m mcat.Manifest, with mcat.Rendering) (map[string]any, map[string]string) {
|
|
if !yields(m) {
|
|
return nil, nil
|
|
}
|
|
engine := mcat.Manifest{Module: engineModule}
|
|
for _, e := range r.Modules {
|
|
if e.Module == engineModule {
|
|
engine = e
|
|
}
|
|
}
|
|
share := mcat.BuildCPUDefaultPercent
|
|
for _, s := range Effective(engine, with.Settings[engineModule]) {
|
|
if s.Key == mcat.BuildCPUShareSetting {
|
|
if n, ok := percentOf(s.Value); ok {
|
|
share = n
|
|
}
|
|
}
|
|
}
|
|
return map[string]any{"priority": "idle", "cpu-share": share},
|
|
map[string]string{mcat.BuildCPUShareWord: strconv.Itoa(share)}
|
|
}
|
|
|
|
// yields is whether a module claims a seat that yields.
|
|
func yields(m mcat.Manifest) bool {
|
|
for _, c := range m.Claims {
|
|
if s, ok := mcat.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
|
|
}
|