package main import ( "errors" "fmt" "os" "path/filepath" ) // **The build agent says it is ready** (novox/hq issue 544). It listens on nothing, so no http or tcp // check can see it work; it writes a mark once it is bound to its worker and pulls build work, and its // container's health check runs `mesh-builder ready`, which passes only while the mark is there. Without // it the node-engine could judge the agent only alive, and every walk that moved it waited out the whole // grace on each machine. // // The mark lives in the container's own temporary directory, never in the workspace the machine keeps: // a new container starts without it, and a restarted one removes it before it binds again. func readyMark() string { return filepath.Join(os.TempDir(), "mesh-builder.ready") } // notReady removes the mark: a holder starting is not taking work until it says so again. func notReady() error { if err := os.Remove(readyMark()); err != nil && !errors.Is(err, os.ErrNotExist) { return fmt.Errorf("cannot remove the mark that this agent takes build work (%s): %w", readyMark(), err) } return nil } // taking writes the mark. A mark that cannot be written is said, and the agent goes on building: its // check then says it is not ready, which is the truth the gate should hear. func taking(seat string) { if err := os.WriteFile(readyMark(), []byte(seat+"\n"), 0o644); err != nil { fmt.Fprintf(os.Stderr, "cannot mark that this agent takes build work (%s): %v\n", readyMark(), err) return } fmt.Fprintf(os.Stderr, "taking build work from %s\n", seat) } // ready is the health check: nil when this container's agent is bound and pulling build work. func ready() error { if _, err := os.Stat(readyMark()); err != nil { return fmt.Errorf("not taking build work yet: %s is not there", readyMark()) } return nil }