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() }