Files
mesh-catalog/modules/nats/internal/keeper/fill.go
T

75 lines
2.2 KiB
Go

package keeper
import (
"context"
"fmt"
"time"
occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/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() })
}