Leave a record the node's own carried for a module that composes its own, and let that module's apply remove it, so the node's own is not refused for ever (issue 774)
mesh/delivery merged: source.main moved to novox/mesh-host@62b211bb6040
mesh/check checking 1d8d7267584e on 62b211bb6040
mesh/delivery merged: source.main moved to novox/mesh-host@62b211bb6040
mesh/check checking 1d8d7267584e on 62b211bb6040
On the bus node restic's manifest replaced its process measure by awake (mesh-catalog 35ff67bd). The record of restic.measure was the node's, made while restic was folded, so restic's own apply never saw it, and the guard against removing a placed module's resources refused the node's own apply whole every two minutes from 2026-10-30 19:42: nothing of the node's own applied. Quick fix considered: forget the one record by hand (a hand act on the node; refused). Thorough fix (this): the node's own apply keeps such a record and says so, never refusing or removing it; a module's own apply owns a node record whose id names it, so it alone removes it once neither composition declares it.
This commit is contained in:
+48
-1
@@ -347,8 +347,19 @@ func (sc *Scope) placedOwner(a store.Applied) string {
|
||||
}
|
||||
|
||||
// owns reports whether a record belongs to the scope's module.
|
||||
//
|
||||
// In a module's own apply, a record the node's own composition made for the module while it was folded (recorded as the
|
||||
// node's, its id naming the module) is the module's too: it is the only apply that may remove it once neither
|
||||
// composition declares it (issue 774). One the node's own still declares stays, as another's held resource does.
|
||||
func (sc *Scope) owns(a store.Applied) bool {
|
||||
return store.OwnerOf(a, declaration.ModuleGuess) == sc.Module
|
||||
if store.OwnerOf(a, declaration.ModuleGuess) == sc.Module {
|
||||
return true
|
||||
}
|
||||
if sc.Module == store.NodeModule || a.Module != store.NodeModule {
|
||||
return false
|
||||
}
|
||||
m, ok := declaration.ModuleGuess(a.ID)
|
||||
return ok && m == sc.Module
|
||||
}
|
||||
|
||||
// isNode is whether the scope is the node's own composition, the one that carries identities, groups, libraries and
|
||||
@@ -473,6 +484,29 @@ func applyScoped(
|
||||
}
|
||||
}
|
||||
|
||||
// **A resource the node's own carried for a module that now has a composition of its own is that module's to remove**
|
||||
// (issue 774, 2026-10-30 on the bus node): recorded as the node's while the module was folded, it is no longer in the
|
||||
// node's own composition and no longer in the module's own either (restic's measure, replaced by awake). The node's own
|
||||
// apply leaves it, record and all, and says so; the module's own apply sees it as its own (Scope.owns) and removes it.
|
||||
// Refused instead, the node's own applied nothing at all, every two minutes, for as long as the record stayed.
|
||||
takenByItsModule := map[string]string{}
|
||||
if scope != nil && scope.Module == store.NodeModule {
|
||||
composes := map[string]bool{}
|
||||
for _, r := range scope.Others {
|
||||
if m := r.DeclaredModule(); m != "" && m != store.NodeModule {
|
||||
composes[m] = true
|
||||
}
|
||||
}
|
||||
for _, orphan := range known.Orphans(declared, origin) {
|
||||
if orphan.Module != store.NodeModule {
|
||||
continue
|
||||
}
|
||||
if m, ok := declaration.ModuleGuess(orphan.ID); ok && composes[m] {
|
||||
takenByItsModule[orphan.ID] = m
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **A module a want still places here is never removed by another's apply** (issue 774): its resources go only with
|
||||
// its own apply or its want's removal. One that would is refused whole, before anything is changed, naming them: a
|
||||
// composition that leaves them out lost what runs, and removing what runs is the worst a node can do with that.
|
||||
@@ -485,6 +519,9 @@ func applyScoped(
|
||||
if _, kept := heldByOthers[orphan.ID]; kept {
|
||||
continue
|
||||
}
|
||||
if _, kept := takenByItsModule[orphan.ID]; kept {
|
||||
continue
|
||||
}
|
||||
if m := scope.placedOwner(orphan); m != "" {
|
||||
refused = append(refused, orphan.ID+" of "+m)
|
||||
}
|
||||
@@ -513,6 +550,16 @@ func applyScoped(
|
||||
log(fmt.Sprintf(" kept %s (%s): %s", orphan.ID, orphan.Target, detail))
|
||||
return nil
|
||||
}
|
||||
if module, taken := takenByItsModule[orphan.ID]; taken {
|
||||
detail := "no longer declared here; " + module + " has a composition of its own here, whose apply removes it, " +
|
||||
"so it was left as it is"
|
||||
report.Outcomes = append(report.Outcomes, Outcome{
|
||||
ID: orphan.ID, Type: orphan.Type, Target: orphan.Target,
|
||||
Action: "kept", Detail: detail,
|
||||
})
|
||||
log(fmt.Sprintf(" kept %s (%s): %s", orphan.ID, orphan.Target, detail))
|
||||
return nil
|
||||
}
|
||||
if by, held := heldFiles[fileKey(orphan)]; held && by != orphan.ID {
|
||||
if scope != nil && !declared[by] {
|
||||
// Another module declares the path: it is that module's, so this record is let go and the file is
|
||||
|
||||
Reference in New Issue
Block a user