Files
mesh-sdk/go/process/ownbuild.go
T
jschoubben b37ed85559 R-1: W1.3: a process reads its own build from MESH_FINGERPRINT once, and says it
The node-engine hands each process the fingerprint of the want it applies (design 47, The fingerprint handover; mesh-host
W13.1). process.OwnBuild reads it once at the first ask, which Connect and Dial make before they dial, and says it in
the journal; with none, or one that is no single word, it says "own build unknown" and why.

Builds: design 47 G §201, §205, §239

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
2026-11-11 10:51:06 +01:00

63 lines
2.3 KiB
Go

package process
import (
"fmt"
"log"
"os"
"strings"
"sync"
)
// FingerprintEnv is the environment value the node-engine starts each process with, a service and a container alike:
// the fingerprint of the want it applies (novox/hq ADR 0656; design 47 *The fingerprint handover*).
const FingerprintEnv = "MESH_FINGERPRINT"
// OwnBuildUnknown is what a process started with no fingerprint says of its own build, in its journal and to whoever
// reads it (the node-engine's process builds, the indexer acting on it as ADR 0639 §8 has it).
const OwnBuildUnknown = "own build unknown"
// Build is the build a process was started with: its fingerprint, or why it is unknown.
type Build struct {
Fingerprint string `json:"fingerprint,omitempty"`
// Unknown says why there is no fingerprint, starting with OwnBuildUnknown; empty when there is one.
Unknown string `json:"unknown,omitempty"`
}
// String is the fingerprint, or why the build is unknown.
func (b Build) String() string {
if b.Fingerprint != "" {
return b.Fingerprint
}
return b.Unknown
}
// ReadOwnBuild is the build getenv's FingerprintEnv names: one word, or unknown with the reason.
func ReadOwnBuild(getenv func(string) string) Build {
fp := strings.TrimSpace(getenv(FingerprintEnv))
switch {
case fp == "":
return Build{Unknown: OwnBuildUnknown + ": started without " + FingerprintEnv}
case strings.ContainsAny(fp, " \t\r\n"):
return Build{Unknown: fmt.Sprintf("%s: %s %q is not one fingerprint", OwnBuildUnknown, FingerprintEnv, fp)}
}
return Build{Fingerprint: fp}
}
// sayOwnBuild writes the process's own build in its journal; a variable so a test reads what it says.
var sayOwnBuild = func(b Build) { log.Printf("own build: %s", b) }
// readAndSay reads the build from this process's environment and says it.
func readAndSay() Build {
b := ReadOwnBuild(os.Getenv)
sayOwnBuild(b)
return b
}
// ownBuild is read once; a test that reads it makes it again (sync.OnceValue(readAndSay)) and puts it back.
var ownBuild = sync.OnceValue(readAndSay)
// OwnBuild is this process's own build, read once from its environment at the first ask and said in its journal then;
// every later ask answers the same, whatever the environment says since. Connect and Dial ask it, so every process
// that reaches the bus says it at its start.
func OwnBuild() Build { return ownBuild() }