route-proxy leaves the controller's repository, which is archived, and nothing registered a move since the controller went: the indexer left a module named by another repository's merge as it was, forever. Now that merge waits, and the holding repository's merge that drops the module hands it over in place, so its key never goes missing between the two; merged the other way round, the key is deleted and written new. A trunk that still holds the module keeps it (ADR 0420 clause 7, ADR 0501 clause 3). Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
70 lines
2.9 KiB
Go
70 lines
2.9 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
// A module moves between repositories by the merges of the delivery group that moves it (novox/hq ADR 0420 clause 7, ADR
|
|
// 0501 clause 3; issue 1126: route-proxy leaves the controller's repository, which is archived). The merge of the
|
|
// repository it moves to names it while the indexer holds it of another: that merge leaves it, says so, and waits here.
|
|
// The merge of the repository that held it, whose trunk no longer holds it, then hands it over: the module is written from
|
|
// the waiting merge, in place, so its key never goes missing between the two (dropRemoved). Merged the other way round,
|
|
// the first merge deletes the key and the second writes it as a new module. Nothing else moves a module: a merge of a
|
|
// repository naming a module whose holding trunk still holds it changes nothing.
|
|
//
|
|
// The wait is the indexer's memory of a merge it heard, not state of its own: an indexer started between the two merges
|
|
// has forgotten it, and the module is deleted by the second; the next merge of the repository it moved to writes it.
|
|
|
|
// waitToMove keeps, by modules key, the part of a merged message naming one module directory the indexer holds of another
|
|
// repository. A later merge of the same repository replaces it.
|
|
func (ix *Indexer) waitToMove(key string, f delivery.Forge, dir string) {
|
|
one := delivery.Forge{V: f.V, Kind: f.Kind, Repository: f.Repository, Branch: f.Branch, Number: f.Number, Merge: f.Merge, Root: f.Root,
|
|
Trees: map[string]string{dir: f.Trees[dir]}, Manifests: map[string]string{dir: f.Manifests[dir]}}
|
|
if l := f.Locks[dir]; len(l) > 0 {
|
|
one.Locks = map[string]map[string]string{dir: l}
|
|
}
|
|
if p := f.Paths[dir]; len(p) > 0 {
|
|
one.Paths = map[string]map[string]string{dir: p}
|
|
}
|
|
if p := f.Packages[dir]; len(p) > 0 {
|
|
one.Packages = map[string][]string{dir: p}
|
|
}
|
|
ix.mu.Lock()
|
|
defer ix.mu.Unlock()
|
|
if ix.moving == nil {
|
|
ix.moving = map[string]delivery.Forge{}
|
|
}
|
|
ix.moving[key] = one
|
|
}
|
|
|
|
// movingTo says a merge of another repository than from waits to take the module at key.
|
|
func (ix *Indexer) movingTo(key, from string) bool {
|
|
ix.mu.Lock()
|
|
defer ix.mu.Unlock()
|
|
f, ok := ix.moving[key]
|
|
return ok && !delivery.SameRepository(f.Repository, from)
|
|
}
|
|
|
|
// handOver writes the module at key from the merge waiting to take it, and forgets the wait.
|
|
func (ix *Indexer) handOver(ctx context.Context, key string) error {
|
|
ix.mu.Lock()
|
|
f, ok := ix.moving[key]
|
|
delete(ix.moving, key)
|
|
ix.mu.Unlock()
|
|
if !ok {
|
|
return nil
|
|
}
|
|
w, err := ix.applyMoving(ctx, f, false, map[string]bool{key: true})
|
|
if err != nil {
|
|
return fmt.Errorf("modules.%s, moving to %s: %w", key, f.Repository, err)
|
|
}
|
|
// A module moved in is judged as a merge's are (ADR 0578 §1, ADR 0579 §1).
|
|
if _, err := ix.JudgeAll(ctx, w.fresh); err != nil {
|
|
ix.logf("judge: the manifests are not judged after moving %s to %s: %v", key, f.Repository, err)
|
|
}
|
|
return nil
|
|
}
|