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`.
20 lines
1.1 KiB
SQL
20 lines
1.1 KiB
SQL
-- The records already made are completed where the mesh can tell: a pin naming a node on which
|
|
-- exactly one assigned module offers the provision (or is the module itself, for a requirement that
|
|
-- names a module) gets that module. A node that answers twice is left to say which — the resolver
|
|
-- refuses it with the module asked for, rather than this guessing on its behalf.
|
|
update provision_pin p
|
|
set module = sub.module
|
|
from (
|
|
select p2.node, p2.name, min(a.module) as module, count(distinct a.module) as answers
|
|
from provision_pin p2
|
|
join assignment a on a.node = p2.provider
|
|
join module m on m.name = a.module
|
|
where p2.module is null
|
|
and (a.module = p2.name
|
|
or exists (select 1
|
|
from jsonb_array_elements(coalesce(m.manifest -> 'provides', '[]'::jsonb)) e
|
|
where (case when jsonb_typeof(e) = 'string' then e #>> '{}' else e ->> 'name' end) = p2.name))
|
|
group by p2.node, p2.name
|
|
) sub
|
|
where sub.node = p.node and sub.name = p.name and sub.answers = 1;
|