Let a module-declared seat carry needs, so mail-notifier can need node-notifier (issue 802)
ADR 0220's dependency mechanism served compiled seats only and retired its one user with
node-resolver-config (commit f68521da). ADR 0378 S8 revives it for module-declared seats:
SeatDeclaration gains Needs, judged by the catalogue check (node scope only, a name that
resolves to a node seat somewhere in the catalogue, never itself), and DependsOn now takes
the catalogue so a claimed seat's needs are found wherever they are declared.
This commit is contained in:
@@ -71,6 +71,12 @@ type SeatDeclaration struct {
|
||||
// mesh's own seats name theirs by: a node seat only, each absolute and literal, and none another seat
|
||||
// names. A module's seat never steps back.
|
||||
Paths []string `json:"paths,omitempty"`
|
||||
// Needs is every node seat this seat's holder needs held on its own node (novox/hq ADR 0220, ADR
|
||||
// 0378 §8): a role whose holder is only right while another role is filled beside it. A module
|
||||
// claiming this seat depends on each, exactly as a module declaring a service depends on the
|
||||
// service manager (ADR 0207) — derived from the claim, never written again in the claimant's own
|
||||
// manifest. Only a node seat may carry needs, and a compiled seat carries none.
|
||||
Needs []string `json:"needs,omitempty"`
|
||||
}
|
||||
|
||||
// KindedBenches are the seats that may be kinded (novox/hq ADR 0234 §2): `channel` sends to the operator,
|
||||
@@ -168,6 +174,7 @@ func declaredSeatProblems(m Manifest) []string {
|
||||
}
|
||||
problems = append(problems, trafficProblems(m, s)...)
|
||||
problems = append(problems, declaredSeatPathProblems(m, s)...)
|
||||
problems = append(problems, declaredSeatNeedsProblems(m, s)...)
|
||||
}
|
||||
|
||||
for _, u := range m.Uses {
|
||||
@@ -228,6 +235,30 @@ func trafficProblems(m Manifest, s SeatDeclaration) []string {
|
||||
return problems
|
||||
}
|
||||
|
||||
// declaredSeatNeedsProblems is what one declaration's needs can be judged on alone (novox/hq ADR
|
||||
// 0378 §8): only a node seat is ever held beside another on the same node, so only a node seat may
|
||||
// carry needs; and a seat needing itself names nothing that was not already true of holding it.
|
||||
// Whether each named need itself exists as a node seat somewhere in the catalogue is CatalogueProblems'
|
||||
// to say, once every manifest is known.
|
||||
func declaredSeatNeedsProblems(m Manifest, s SeatDeclaration) []string {
|
||||
var problems []string
|
||||
if len(s.Needs) == 0 {
|
||||
return problems
|
||||
}
|
||||
if s.At() != ScopeNode {
|
||||
problems = append(problems, fmt.Sprintf(
|
||||
"%s declares %s needing %s, and only a node seat needs another held beside it "+
|
||||
"(novox/hq ADR 0378 §8)", m.Module, s.Name, strings.Join(s.Needs, ", ")))
|
||||
}
|
||||
for _, need := range s.Needs {
|
||||
if need == s.Name {
|
||||
problems = append(problems, fmt.Sprintf(
|
||||
"%s declares %s needing itself (novox/hq ADR 0378 §8)", m.Module, s.Name))
|
||||
}
|
||||
}
|
||||
return problems
|
||||
}
|
||||
|
||||
// A Shelf is every manifest the mesh has registered, by module name.
|
||||
type Shelf map[string]Manifest
|
||||
|
||||
@@ -280,6 +311,36 @@ func CatalogueProblems(shelf Shelf) []string {
|
||||
return ok
|
||||
}
|
||||
|
||||
// atNode says whether a seat, compiled or declared, is a node seat — judged here because only
|
||||
// the whole catalogue knows a declared one's scope (novox/hq ADR 0378 §8).
|
||||
atNode := func(seat string) bool {
|
||||
if s, isMesh := SeatNamed(seat); isMesh {
|
||||
return s.Scope == ScopeNode
|
||||
}
|
||||
if s, ok := declared[seat]; ok {
|
||||
return s.At() == ScopeNode
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// A module-declared seat's needs name node seats that hold beside it (novox/hq ADR 0378 §8):
|
||||
// whether one exists at all, compiled or declared by any module, only the whole catalogue can
|
||||
// say — a single manifest's own problems (declaredSeatProblems) judge its needs no further.
|
||||
for _, module := range shelfOrder(shelf) {
|
||||
for _, s := range shelf[module].DefinesSeats {
|
||||
for _, need := range s.Needs {
|
||||
if !exists(need) {
|
||||
problems = append(problems, fmt.Sprintf(
|
||||
"%s declares %s needing %s, "+UndeclaredSeat, module, s.Name, need))
|
||||
} else if !atNode(need) {
|
||||
problems = append(problems, fmt.Sprintf(
|
||||
"%s declares %s needing %s, which is not a node seat (novox/hq ADR 0378 §8)",
|
||||
module, s.Name, need))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Which seats name each path (novox/hq ADR 0287): a module's seat naming one another seat names loses.
|
||||
named, pathProblems := pathSeats(shelfOrder(shelf), shelf, declaredBy)
|
||||
problems = append(problems, pathProblems...)
|
||||
|
||||
Reference in New Issue
Block a user