Assign around what a machine already holds
The other half of ADR 0038, and what 04-ISSUES/028 was actually about. A module can now avoid colliding with another module; until this it could not avoid colliding with the mesh itself. The substrate is not a module. A node raises it from the bundle it carries before any mesh exists, so the control plane had never heard of the store, the broker, or its own container — and handed a database module 5432, which the store already had. So the machine says. The host records what each resource binds, distinguishing what it carried from what the mesh sent — a distinction that already existed so the two never remove each other — and reports the carried ones. The node states and this context writes, which is the shape of every message between them. What the declaration binds, not what is open. A machine's open ports are a moving target, and assigning around them would mean a port that was free when it was asked for and taken when it was used. Replaced whole each time rather than merged: a machine that gave a port back must be believed about that too, and a set that only grows keeps a port reserved for something no longer there. Tested against a real database, and the tests bite — removing the check hands the module 20000, which the machine had said it holds.
This commit is contained in:
@@ -76,6 +76,35 @@ func (i *Inventory) PortFor(
|
||||
return i.assignPort(ctx, record.ID, node, module, wanted, fixed)
|
||||
}
|
||||
|
||||
// RecordCarried keeps what a machine says it already holds, replacing whatever it said before.
|
||||
//
|
||||
// **Replaced whole, not merged.** A machine that gave a port back must be believed about that too,
|
||||
// and a set the mesh only ever adds to would keep a port reserved for something that is no longer
|
||||
// there.
|
||||
func (i *Inventory) RecordCarried(ctx context.Context, node string, ports []int) error {
|
||||
record, err := i.NodeByName(ctx, node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ports == nil {
|
||||
ports = []int{}
|
||||
}
|
||||
_, err = i.store.Pool().Exec(ctx,
|
||||
`update node set carried_ports = $2 where id = $1`, record.ID, ports)
|
||||
return err
|
||||
}
|
||||
|
||||
// carriedOn is what a machine said it already holds.
|
||||
func (i *Inventory) carriedOn(ctx context.Context, nodeID any) ([]int, error) {
|
||||
var ports []int
|
||||
err := i.store.Pool().QueryRow(ctx,
|
||||
`select carried_ports from node where id = $1`, nodeID).Scan(&ports)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
func (i *Inventory) freePort(ctx context.Context, node any, module string, wanted int) error {
|
||||
_, err := i.store.Pool().Exec(ctx,
|
||||
`delete from port_assignment where node = $1 and module = $2 and wanted = $3`,
|
||||
@@ -90,6 +119,18 @@ func (i *Inventory) assignPort(
|
||||
if err != nil {
|
||||
return Assigned{}, err
|
||||
}
|
||||
// And what the machine itself says it already holds — the substrate it raised before there
|
||||
// was a mesh to ask (novox/hq ADR 0038). Not assignments: nothing here chose them, and
|
||||
// nothing here can move them.
|
||||
carried, err := i.carriedOn(ctx, nodeID)
|
||||
if err != nil {
|
||||
return Assigned{}, err
|
||||
}
|
||||
for _, port := range carried {
|
||||
if _, mine := taken[port]; !mine {
|
||||
taken[port] = "something this machine already runs"
|
||||
}
|
||||
}
|
||||
|
||||
machine := wanted
|
||||
if !fixed {
|
||||
|
||||
Reference in New Issue
Block a user