Each of mesh-build-go, -node and -image declares cores-per-step (6, 2, 2) and hands it to the SDK puller, which bounds the configured capacity by floor(slice quota cores / cores-per-step), read live; thread limits and the status tools follow the effective capacity (issue 1806's follow-up: three Go checks on shanks' 12-core slice starved past the 30-minute step bound). mesh-build-go says its lint and test phases with the ask id (issue 1890).
43 lines
1.8 KiB
Go
43 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"git.novox.be/novox/mesh-sdk/go/buildcpu"
|
|
"git.novox.be/novox/mesh-sdk/go/buildstep"
|
|
)
|
|
|
|
// The processors a step may take (novox/hq ADR 0553, issue 1806). The node-engine holds this module's runtime, with
|
|
// every other build module's of the node, in one slice at idle priority under the node's one share of its processors:
|
|
// that quota bounds the total. Threads only size each step: the share the composer gives (buildstep.NodeLimits) over
|
|
// this module's own capacity, so a step does not wait in the kernel's throttle. Without the composer's share there is
|
|
// no slice to size a step to, and no thread limit is set.
|
|
|
|
// cpuLimits is what one step is held to now.
|
|
func (m *Module) cpuLimits() buildcpu.Limits {
|
|
slots := 1
|
|
switch {
|
|
case m.Held != nil:
|
|
slots = m.Held.CapacityNow() // the capacity the puller judges by, bounded by the node's build slice
|
|
case m.Capacity != nil:
|
|
slots = m.Capacity()
|
|
case m.Settings != "":
|
|
slots = buildstep.NodeCapacity(m.Settings, buildstep.DefaultCapacities, m.Node, nil)()
|
|
}
|
|
return buildstep.NodeLimits(slots)
|
|
}
|
|
|
|
// threadEnv is the environment (nothing without a share) every command of a step is given for its threads: GOMAXPROCS for esbuild and every Go
|
|
// program, UV_THREADPOOL_SIZE for Node's worker pool.
|
|
func (m *Module) threadEnv() []string {
|
|
return buildcpu.Env(m.cpuLimits().Threads)
|
|
}
|
|
|
|
// cpuStatus is what the status tool says of it: the limits a step is given, and what the kernel holds this runtime
|
|
// to (its unit and its slice), read from its cgroup rather than assumed.
|
|
func (m *Module) cpuStatus() map[string]any {
|
|
out := map[string]any{"limits": m.cpuLimits(), "in-force": buildcpu.ReadInForce()}
|
|
if m.Held != nil {
|
|
out["capacity"] = m.Held.CapacityDetail() // the capacity judged by and why (issue 1806's follow-up)
|
|
}
|
|
return out
|
|
}
|