package main import ( "context" "fmt" "sort" "strings" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/health" ) // ReadingTools are the tools over the state `readings`: every key, one key, how full the state is, and one item // measured now (a module's tools are its command line). func ReadingTools(k *Keeper) []stdio.Tool { return []stdio.Tool{ { Name: "disk_readings", Description: "The data readings disk-load keeps for this machine's data items (ADR 0233, ADR 0571 clause 3): every key " + "`..` with its size, newest write, measured-at, precision and seven-day peak, or one key with " + "all it holds when `key` is given; and how full the state is: keys kept, their bytes, and the cap the bus puts on " + "a state (none declared). Filter by `module`. (r)", Input: map[string]any{ "key": map[string]any{"type": "string", "description": "one key, .., with everything it holds"}, "module": map[string]any{"type": "string", "description": "only this module's items"}, }, Run: func(args map[string]any) (any, error) { if key := text(args, "key"); key != "" { raw, err := k.Store.Get(key) if err != nil { return nil, err } if len(raw) == 0 { return nil, fmt.Errorf("no reading is kept at %q", key) } r, err := health.DecodeReading(raw) return r, err } keys, err := k.Store.Keys() if err != nil { return nil, err } sort.Strings(keys) module := text(args, "module") type line struct { Key string `json:"key"` SizeBytes *int64 `json:"size_bytes,omitempty"` PeakBytes *int64 `json:"peak_bytes,omitempty"` Precision string `json:"precision,omitempty"` Error string `json:"error,omitempty"` Reading health.Reading `json:"-"` } var lines []line total := 0 for _, key := range keys { raw, err := k.Store.Get(key) if err != nil { return nil, err } total += len(raw) r, err := health.DecodeReading(raw) if err != nil || (module != "" && r.Module != module) { continue } lines = append(lines, line{Key: key, SizeBytes: r.SizeBytes, PeakBytes: r.Peak, Precision: r.Precision, Error: r.Error}) } return map[string]any{"readings": lines, "fill": map[string]any{"keys": len(keys), "bytes": total, "cap": "none declared: the bus's own limit on a state applies"}}, nil }, }, { Name: "disk_measure", Description: "Measure one data item of this machine now, whatever its method (a walk too), and write its reading when it " + "changed. Reads the disks as root: a walk is bounded by time and files and says when it was partial.", Input: map[string]any{ "module": map[string]any{"type": "string", "description": "the module that declares the item"}, "item": map[string]any{"type": "string", "description": "the item's id"}, }, Run: func(args map[string]any) (any, error) { module, item := text(args, "module"), text(args, "item") if module == "" || item == "" { return nil, fmt.Errorf("module and item are required") } r, written, err := k.MeasureNow(context.Background(), module, item) if err != nil { return nil, err } return map[string]any{"written": written, "reading": r, "key": health.ReadingKey(k.Node, module, item), "note": strings.TrimSpace(map[bool]string{true: "the reading changed and was written", false: "the reading had not changed"}[written])}, nil }, }, } }