A command opens each store once, not once per machine
Working out what a machine should be reaches the identity context for its certificate and the licence context for its model access. Both were opened — and waited on — inside functions called for every node in a push. Two machines hid it. Fifty would be fifty connect-and-wait cycles for data that does not change while the push runs. So a command holds what it has open, and passes it. Each context is opened on first use rather than up front, because most commands need one and paying to reach three would be the same waste from the other side. The contexts stay separate, which is the point: this is one struct holding three connections to three databases, not one connection to a shared one. No context reaches another's store, and each still holds only its own credential (novox/hq ADR 0008). A pure move again — the gate is green before and after, and no test changed.
This commit is contained in:
+22
-18
@@ -25,11 +25,12 @@ import (
|
||||
|
||||
// serve is the control plane running: one connection to the broker, one queue, one consumer.
|
||||
func serve(ctx context.Context) error {
|
||||
inv, err := openInventory(ctx)
|
||||
open, err := openStores(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inv.Close()
|
||||
defer open.Close()
|
||||
inv := open.inventory
|
||||
|
||||
ident, err := openIdentity(ctx)
|
||||
if err != nil {
|
||||
@@ -100,11 +101,12 @@ func declare(ctx context.Context, args []string) error {
|
||||
|
||||
// The node has to exist before it can be told anything. Publishing to a queue nobody consumes
|
||||
// would sit there looking like success.
|
||||
inv, err := openInventory(ctx)
|
||||
open, err := openStores(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inv.Close()
|
||||
defer open.Close()
|
||||
inv := open.inventory
|
||||
if _, err := inv.NodeByName(ctx, node); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -155,11 +157,12 @@ func pushCommand(ctx context.Context, args []string) error {
|
||||
return errors.New("push <node> or push --behind, not both: one names a machine and the " +
|
||||
"other asks which machines need one")
|
||||
}
|
||||
inv, err := openInventory(ctx)
|
||||
open, err := openStores(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inv.Close()
|
||||
defer open.Close()
|
||||
inv := open.inventory
|
||||
|
||||
ident, err := openIdentity(ctx)
|
||||
if err != nil {
|
||||
@@ -190,7 +193,7 @@ func pushCommand(ctx context.Context, args []string) error {
|
||||
// only "failed or refused", so a machine that applied cleanly and whose declaration has
|
||||
// since changed was not behind — and novox/hq ADR 0010's question, *did my change go
|
||||
// out?*, was answerable only for the machines that broke.
|
||||
would, err := wouldSend(ctx, inv, nodes)
|
||||
would, err := wouldSend(ctx, open, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -211,7 +214,7 @@ func pushCommand(ctx context.Context, args []string) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
gens, err := generators(ctx, inv)
|
||||
gens, err := generators(ctx, open)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -254,7 +257,7 @@ func pushCommand(ctx context.Context, args []string) error {
|
||||
n.Name, doing.Outcome, doing.At.Local().Format("2006-01-02 15:04"))
|
||||
}
|
||||
}
|
||||
plan, settings, err := planFor(ctx, inv, n.Name)
|
||||
plan, settings, err := planFor(ctx, open, n.Name)
|
||||
if err != nil {
|
||||
refusals = append(refusals, fmt.Sprintf("%s:\n%v", n.Name, err))
|
||||
continue
|
||||
@@ -262,7 +265,7 @@ func pushCommand(ctx context.Context, args []string) error {
|
||||
// The private network is in here with everything else. It used to be composed separately
|
||||
// and prepended, which meant every machine with an address was on it and no machine could
|
||||
// be kept off. It is a module now, so it arrives the way a module does.
|
||||
resources, err := declarationWith(ctx, inv, n.Name, plan, settings, gens)
|
||||
resources, err := declarationWith(ctx, open, n.Name, plan, settings, gens)
|
||||
if err != nil {
|
||||
refusals = append(refusals, fmt.Sprintf("%s:\n%v", n.Name, err))
|
||||
continue
|
||||
@@ -307,14 +310,15 @@ func pushCommand(ctx context.Context, args []string) error {
|
||||
// The same all-or-nothing rule push follows, and for the same reason: a rotation that reached the
|
||||
// consumer and refused on the provider would leave one end holding a credential the other has
|
||||
// never heard of — which is the state this whole mechanism exists to make impossible.
|
||||
func sendTo(ctx context.Context, inv *inventory.Inventory, names []string) error {
|
||||
func sendTo(ctx context.Context, open *stores, names []string) error {
|
||||
inv := open.inventory
|
||||
ident, err := openIdentity(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer ident.Close()
|
||||
|
||||
gens, err := generators(ctx, inv)
|
||||
gens, err := generators(ctx, open)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -326,12 +330,12 @@ func sendTo(ctx context.Context, inv *inventory.Inventory, names []string) error
|
||||
var sending []ready
|
||||
var refusals []string
|
||||
for _, name := range names {
|
||||
plan, settings, err := planFor(ctx, inv, name)
|
||||
plan, settings, err := planFor(ctx, open, name)
|
||||
if err != nil {
|
||||
refusals = append(refusals, fmt.Sprintf("%s:\n%v", name, err))
|
||||
continue
|
||||
}
|
||||
resources, err := declarationWith(ctx, inv, name, plan, settings, gens)
|
||||
resources, err := declarationWith(ctx, open, name, plan, settings, gens)
|
||||
if err != nil {
|
||||
refusals = append(refusals, fmt.Sprintf("%s:\n%v", name, err))
|
||||
continue
|
||||
@@ -382,20 +386,20 @@ func digestOf(body []byte) string {
|
||||
//
|
||||
// Machines that do not resolve are left out rather than reported as waiting: "this machine cannot
|
||||
// be worked out" is a different problem with a different remedy, and `plan` is where it is said.
|
||||
func wouldSend(ctx context.Context, inv *inventory.Inventory,
|
||||
func wouldSend(ctx context.Context, open *stores,
|
||||
nodes []inventory.Node) (map[string]string, error) {
|
||||
|
||||
gens, err := generators(ctx, inv)
|
||||
gens, err := generators(ctx, open)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := map[string]string{}
|
||||
for _, n := range nodes {
|
||||
plan, settings, err := planFor(ctx, inv, n.Name)
|
||||
plan, settings, err := planFor(ctx, open, n.Name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resources, err := declarationWith(ctx, inv, n.Name, plan, settings, gens)
|
||||
resources, err := declarationWith(ctx, open, n.Name, plan, settings, gens)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user