An older build request never replaces a newer one's artifact
Builds of one module in flight together finish in any order, and the mesh took whatever it heard last as what the module is: RegisterModule overwrote the module's manifest unconditionally, and Held/BuiltAgainst/ReadRepositories ordered builds by when they were recorded. A postgres build asked before the mesh-tools runtime fix finished after the one asked after it, and the next push deployed the stale image (novox/hq issue 219). A build is now ordered by when it was asked, read from the build-<nanos> id the controller writes: build.asked and module.built_asked (migration 0055). A registration from an earlier request than the module's current one is recorded and refused as superseded. A plan takes as its outcome only a build asked at or after its own ask, so an earlier plan's leftover build cannot settle a later plan. Ids of any other shape keep the old order.
This commit is contained in:
@@ -2,6 +2,9 @@ package link
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Asking a machine to build a module, and hearing what came out.
|
||||
@@ -17,6 +20,32 @@ import (
|
||||
// holds no opinion about what they contain, and a host that also built things would be a host
|
||||
// with a container runtime requirement and a git dependency (novox/hq ADR 0005).
|
||||
|
||||
// NewBuildID is the correlation for a build asked at that moment: `build-<unix nanoseconds>`.
|
||||
//
|
||||
// **The id carries when the build was asked, and that is read back** (novox/hq 04-ISSUES/219). Builds
|
||||
// of one module can be in flight together and finish in any order; what a module currently is must
|
||||
// be the newest *request's* outcome, not the last one heard, and the id is the one thing every
|
||||
// outcome echoes whichever builder answered it. One place writes the shape and one reads it.
|
||||
func NewBuildID(asked time.Time) string {
|
||||
return "build-" + strconv.FormatInt(asked.UnixNano(), 10)
|
||||
}
|
||||
|
||||
// BuildAskedAt is when the build with this id was asked, as NewBuildID wrote it. False for an id
|
||||
// of any other shape — one written before this was read, or by hand — whose request time the mesh
|
||||
// does not know.
|
||||
func BuildAskedAt(id string) (time.Time, bool) {
|
||||
digits, ok := strings.CutPrefix(id, "build-")
|
||||
if !ok || digits == "" {
|
||||
return time.Time{}, false
|
||||
}
|
||||
nanos, err := strconv.ParseInt(digits, 10, 64)
|
||||
// A number too small to be a moment this mesh could have asked at is a name, not a time.
|
||||
if err != nil || nanos < time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).UnixNano() {
|
||||
return time.Time{}, false
|
||||
}
|
||||
return time.Unix(0, nanos).UTC(), true
|
||||
}
|
||||
|
||||
// BuildRequest is one module to build.
|
||||
type BuildRequest struct {
|
||||
// ID correlates the answer with the asking. Not the module name: two builds of one module can
|
||||
|
||||
Reference in New Issue
Block a user