Read a shrink against the item's own path, so a moved directory starts its size history again (hq issue 368)
mesh/merge-gate pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without …
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request

A reading now keeps the path it was measured at, and the peak is read only from
readings at the item's path now. Before, an agent's home that moved to its own
account was compared with the operator's home it left, and data-shrank was
raised for data that was never lost. Existing readings take their item's path
now, so a shrink that is real stays raised.
This commit is contained in:
jochen
2026-10-10 17:42:46 +02:00
parent 4d30b5de13
commit 96b0966ad8
4 changed files with 120 additions and 8 deletions
+17 -8
View File
@@ -94,7 +94,9 @@ type DataChange struct {
}
// readingEvery is how often a measurement is kept as a reading: the shrink is read over days, and a
// row every five minutes would say the same thing sixty times an hour.
// row every five minutes would say the same thing sixty times an hour. A reading keeps the item's path
// as it stands after the measurement — the holder's, or the last one known when it named none — and an
// item at a path with no recent reading is read at once (novox/hq issue 368).
const readingEvery = 55 * time.Minute
// readingsKept is how long readings are kept.
@@ -187,10 +189,13 @@ func (i *Inventory) RecordData(ctx context.Context, machine string, declared []D
}
if m.Size != nil && m.MeasuredAt != nil && Comparable(m.Precision) {
if _, err := tx.Exec(ctx, `
insert into data_reading (machine, module, item, at, size_bytes, last_write)
select $1, $2, $3, $4, $5, $6
where not exists (select 1 from data_reading
where machine = $1 and module = $2 and item = $3 and at > $4::timestamptz - $7::interval)`,
insert into data_reading (machine, module, item, at, size_bytes, last_write, path)
select $1, $2, $3, $4, $5, $6, d.path
from data_item d
where d.machine = $1 and d.module = $2 and d.item = $3
and not exists (select 1 from data_reading
where machine = $1 and module = $2 and item = $3 and path = d.path
and at > $4::timestamptz - $7::interval)`,
machine, d.Module, d.Item, *m.MeasuredAt, *m.Size, m.LastWrite,
fmt.Sprintf("%d seconds", int(readingEvery.Seconds()))); err != nil {
return change, err
@@ -281,10 +286,14 @@ func (i *Inventory) DataOf(ctx context.Context, machine, module, item string) (D
return r, err
}
// DataPeaks is each item's largest reading since a moment, keyed by DataRecord.Key.
// DataPeaks is each item's largest reading since a moment, keyed by DataRecord.Key — read only from
// readings at the item's path now (novox/hq issue 368): a directory is never compared with another one
// that once held the same item, so a moved item starts its size history again at its new path.
func (i *Inventory) DataPeaks(ctx context.Context, since time.Time) (map[string]int64, error) {
rows, err := i.store.Pool().Query(ctx, `select machine, module, item, max(size_bytes) from data_reading
where at >= $1 group by machine, module, item`, since)
rows, err := i.store.Pool().Query(ctx, `select r.machine, r.module, r.item, max(r.size_bytes)
from data_reading r
join data_item d on d.machine = r.machine and d.module = r.module and d.item = r.item and d.path = r.path
where r.at >= $1 group by r.machine, r.module, r.item`, since)
if err != nil {
return nil, err
}