indexer_placement reads where modules run as the indexer wrote it, by node or by module (issue 1126, ADR 0549 §2)
This commit is contained in:
@@ -20,6 +20,8 @@ import (
|
||||
const (
|
||||
ModuleReadTool = "indexer_module"
|
||||
ModulesReadTool = "indexer_modules"
|
||||
// PlacementReadTool reads the indexer's placement (novox/hq ADR 0549 §2, issue 1126).
|
||||
PlacementReadTool = "indexer_placement"
|
||||
)
|
||||
|
||||
// StateRead reads the indexer's modules state, as the view's reads grant it: its keys and a key's stored value (nil for a key with none).
|
||||
@@ -39,6 +41,7 @@ type Reader struct {
|
||||
WantsState StateRead // the assigner's wants and holds
|
||||
DifferencesState StateRead // the assigner's differences
|
||||
HavesState StateRead // the node-engine's haves
|
||||
PlacementState StateRead // the indexer's placement
|
||||
}
|
||||
|
||||
// Module is the stored value of modules.<module>, exactly as the indexer wrote it.
|
||||
@@ -613,3 +616,55 @@ func (r Reader) Differences(node, module string) (KeptAnswer, error) {
|
||||
func (r Reader) Haves(node, module string) (KeptAnswer, error) {
|
||||
return r.kept(r.HavesState, "the haves", node, module)
|
||||
}
|
||||
|
||||
// Placement is the indexer's placement as stored (ADR 0549 §2): one node's key with node, every node placing a module
|
||||
// with module (each node's key whole, so its pins, ports and bindings are beside the module), and every node's key with
|
||||
// neither. A key that does not read as a placement is listed as unreadable, never dropped.
|
||||
func (r Reader) Placement(node, module string) (map[string]any, error) {
|
||||
node, module = strings.TrimSpace(node), strings.TrimSpace(module)
|
||||
if r.PlacementState.Keys == nil || r.PlacementState.Get == nil {
|
||||
return nil, fmt.Errorf("the placement state cannot be read here")
|
||||
}
|
||||
if node != "" {
|
||||
key, err := delivery.PlacementKey(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw, err := r.PlacementState.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(raw) == 0 {
|
||||
return nil, fmt.Errorf("no placement of %s: the catalogue holds no placement file for it, or the indexer has read none yet", node)
|
||||
}
|
||||
return map[string]any{"placement": map[string]json.RawMessage{node: raw}}, nil
|
||||
}
|
||||
keys, err := r.PlacementState.Keys()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Strings(keys)
|
||||
values, err := r.PlacementState.values(keys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := map[string]json.RawMessage{}
|
||||
var unreadable []string
|
||||
for i, key := range keys {
|
||||
n, err := delivery.ParsePlacementKey(key)
|
||||
if err != nil {
|
||||
unreadable = append(unreadable, key)
|
||||
continue
|
||||
}
|
||||
p, err := delivery.DecodePlacement(values[i])
|
||||
if err != nil {
|
||||
unreadable = append(unreadable, key)
|
||||
continue
|
||||
}
|
||||
if module != "" && !slices.Contains(p.Assigned(), module) {
|
||||
continue
|
||||
}
|
||||
out[n] = values[i]
|
||||
}
|
||||
return map[string]any{"placement": out, "unreadable": unreadable}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user