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
63 lines
2.3 KiB
Go
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() }
|