Files
mesh-catalog/modules/mesh-build-node/cmd/mesh-build-node/room.go
T
jschoubben 9c57f7afb3 mesh-build-go publishes the build runner as its own package, so the other build modules share it without mesh-sdk (ADR 0593 §1)
The runner, the toolchain guard, the fetch, the parsers, buildcpu, the conformance kit and mesh-pack move from mesh-sdk's
buildstep into modules/mesh-build-go/buildstep (own go.mod). mesh-build-go, mesh-build-node and mesh-build-image require it
by a same-repository replace; what the delivery parts read (the failure contract, the fetch request, the stale sweep, the
module tree shape, NewID, CapacitySetting) stays imported from mesh-sdk as sdkstep.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 18:22:41 +01:00

68 lines
2.6 KiB
Go

package main
// A step's room to work and its workspace's end (novox/hq issue 1839, ADR 0509): every step is refused while the work
// or toolchain cache filesystem is under the floor, a workspace is held while a step runs on it, removed when its caller releases
// it, and swept unheld past buildstep.UnheldBound.
import (
"git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep"
stdio "git.novox.be/novox/mesh-sdk/go"
)
// ReleaseTool removes a workspace whose caller's steps have ended.
const ReleaseTool = "build_node_release"
// floorOf is the floor the module keeps on node: build-agent's.
func floorOf(node string) buildstep.Floor {
return buildstep.Floor{Node: node, Bytes: buildstep.FreeSpaceFloor}
}
// room refuses while the work or toolchain cache filesystem is under the floor.
func (m *Module) room() error {
paths := []string{m.Work}
if m.Toolchain != nil {
paths = append(paths, m.Toolchain.Paths.Cache)
}
return m.Floor.Check(paths...)
}
// spaces are the module's workspaces under Work.
func (m *Module) spaces() *buildstep.Workspaces {
m.spacesOnce.Do(func() { m.workspaces = &buildstep.Workspaces{Dir: m.Work} })
return m.workspaces
}
// holdArg holds the workspace a step's arguments name while the step runs; nothing when they name none.
func (m *Module) holdArg(args map[string]any) func() {
ws, _ := args["workspace"].(string)
if ws == "" {
return func() {}
}
return m.spaces().Hold(ws)
}
// releaseTool is build_node_release: no guard and no floor, since it only frees room.
func (m *Module) releaseTool() stdio.Tool {
return stdio.Tool{Name: ReleaseTool,
Description: "Remove a workspace whose steps have ended (fetch, test, build): its caller says so once its last step " +
"answered. A workspace already gone is no error; one a running step holds is refused. A workspace never released " +
"is removed two hours after its last use.",
Input: map[string]any{"type": "object", "properties": map[string]any{
"workspace": map[string]any{"type": "string", "description": "the workspace id a fetch answered"},
}, "required": []string{"workspace"}},
Run: func(args map[string]any) (any, error) {
ws, _ := args["workspace"].(string)
if err := m.spaces().Release(ws); err != nil {
return nil, err
}
return map[string]any{"released": ws}, nil
}}
}
// sweepSaid is CleanWorkspaces' saying of a workspace a caller never released: a fault of the caller (ADR 0509).
func (m *Module) sweepSaid(removed []string) {
if len(removed) > 0 && m.Say != nil {
m.Say("removed %d workspaces no caller released within %s: %v", len(removed), buildstep.UnheldBound, removed)
}
}