A pin names the module as well as the node; a node that answers twice is refused
A provider is a (node, module) pair (design 23), and the pin — the one way a consumer names its provider — named only the node. Two modules on one node can both answer a provision (public-acme and step-ca both offer acme-ca on novox), and then the resolver, given a pin naming that node, took the last provider listed: a coin flip. The same ambiguity beside the consumer was settled by a map walk — random per plan — which is how novox's own route-proxy got its issuer (novox/hq #258). - `pin <node> <provision> <from-node> <module>`: both halves, always. The console gains `pin` and `unpin`. The provider may be on the consumer's own node, since two modules beside it can both answer. - The resolver refuses ambiguity instead of picking, across machines and beside the consumer alike, naming every candidate as node/module and the form of the pin that settles it. A plain capability that grants nothing and serves nothing (three shells beside an editor) is not a choice to put to anybody and stays as it was. - provision_pin gains a nullable module (0050); records made before are completed where the node they name answers once, and left for a person where it answers twice (0051). - The provider of something already satisfied is looked for among what was assigned, not only what the walk has reached — a consumer reached before the provider beside it no longer loses its binding. - The start-time check that every declared verb is runnable samples each verb's required arguments from its schema instead of three guessed keys. Live consequence: a node that has two providers of one bound provision assigned (novox: acme-ca) resolves only once pinned — `pin novox acme-ca novox public-acme`.
This commit is contained in:
@@ -385,19 +385,19 @@ func TestAPinSurvivesAndCanBeChanged(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := inv.PinProvision(ctx, "user", "postgres-database", "first"); err != nil {
|
||||
if err := inv.PinProvision(ctx, "user", "postgres-database", "first", "postgres"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Changing the answer replaces it rather than adding a second, or a machine would be told to
|
||||
// use two databases and nothing would say which.
|
||||
if err := inv.PinProvision(ctx, "user", "postgres-database", "second"); err != nil {
|
||||
if err := inv.PinProvision(ctx, "user", "postgres-database", "second", "postgres"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pins, err := inv.PinsFor(ctx, "user")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(pins) != 1 || pins["postgres-database"] != "second" {
|
||||
if len(pins) != 1 || pins["postgres-database"].Node != "second" || pins["postgres-database"].Module != "postgres" {
|
||||
t.Fatalf("got %v", pins)
|
||||
}
|
||||
if err := inv.UnpinProvision(ctx, "user", "postgres-database"); err != nil {
|
||||
@@ -422,7 +422,7 @@ func TestAPinGoesWhenTheProviderLeavesTheMesh(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := inv.PinProvision(ctx, "consumer", "postgres-database", "provider"); err != nil {
|
||||
if err := inv.PinProvision(ctx, "consumer", "postgres-database", "provider", "postgres"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := inv.store.Pool().Exec(ctx, `delete from node where name = 'provider'`); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user