package keeper import ( "context" "fmt" "time" occ "git.novox.be/novox/mesh-contracts/go/clients/operatorchannelclient" ) // FillPass reads the fill of every entry that refuses when full (ADR 0595 §6), raising `full` at the raise mark and // clearing it only below the clear mark, so an entry at the mark does not flap. It is the keeper's one periodic read. func (k *Keeper) FillPass() { // What the bus did not take before is said again first (design 25 § 12.2). k.SayUnsaid() raise, clear := k.marks() keys, err := k.Store.Keys(StateAsked) if err != nil { k.logf("the fill pass cannot read its own %s: %v", StateAsked, err) return } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() for _, module := range keys { held, _, found := k.asked(module) if !found { continue } changed := false for _, local := range sortedKeys(held.Made) { m := held.Made[local] if !m.Created { continue } var most int64 = -1 for _, o := range m.Plan.Objects { if !o.Settings.Refuses() || o.Settings.MaxBytes <= 0 { continue } _, f, there, err := k.Bus.Held(ctx, o) if err != nil || !there { continue } if p := int64(f.Bytes) * 100 / o.Settings.MaxBytes; p > most { most = p } } if most < 0 { continue } was := m m.Fill = most switch { case !m.Full && most >= raise: m.Full = true k.emit(EventFull, m.Plan, held.Revision, fmt.Sprintf("%d%% of its cap, past the raise mark %d%%", most, raise), nil, nil) k.raise(conditionFull, module, local, occ.SeverityWarning, "Kept data is filling up", "a larger cap in the module's manifest, or data removed", fmt.Sprintf("%s of %s holds %d%% of its cap and refuses new data when full; it is cleared below %d%%", local, module, most, clear)) case m.Full && most < clear: m.Full = false k.emit(EventFullCleared, m.Plan, held.Revision, fmt.Sprintf("%d%% of its cap, below the clear mark %d%%", most, clear), nil, nil) k.clear(conditionFull, module, local) } if m.Fill != was.Fill || m.Full != was.Full { held.Made[local], changed = m, true } } if changed { k.write(held) } } k.setStatus(func(s *Status) { s.Pass = k.now() }) }