Answer mesh/state.info with a bucket's fill and caps, so a bundle's tools can say how full its state is (issue 1952)

This commit is contained in:
2026-10-29 22:43:58 +01:00
parent 9fc97e45c9
commit e9009b7f04
4 changed files with 60 additions and 2 deletions
+45
View File
@@ -174,6 +174,51 @@ func (c *Conn) StateHistory(module, name, key string) ([]StateKept, error) {
return kept, nil
}
// StateInfo is how full a state's bucket is against its caps (tools-are-how-a-module-is-spoken-to): a bundle's tools
// say fill against cap from it.
type StateInfo struct {
State string `json:"state"`
Bucket string `json:"bucket"`
// Bytes is what the bucket holds now, every kept value and marker counted; Keys how many keys it holds, a key
// whose last value is a delete or expiry marker counted until the marker goes.
Bytes uint64 `json:"bytes"`
Keys uint64 `json:"keys"`
// MaxBytes and MaxValueBytes are the bucket's caps; -1 is none.
MaxBytes int64 `json:"max_bytes"`
MaxValueBytes int32 `json:"max_value_bytes"`
// History is how many values a key keeps; TTLSeconds the bucket's age for a value (0 none); KeyTTL whether a key may
// carry its own time to live (issue 1952).
History int64 `json:"history"`
TTLSeconds int64 `json:"ttl_seconds"`
KeyTTL bool `json:"key_ttl"`
}
// StateInfo reads a state's bucket's fill and caps. It is a read like StateGet: served to the owner and every reader.
func (c *Conn) StateInfo(module, name string) (*StateInfo, error) {
s, err := c.issuedState(module, name)
if err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), StateTimeout)
defer cancel()
kv, err := c.bucket(ctx, s)
if err != nil {
return nil, err
}
status, err := kv.Status(ctx)
if err != nil {
return nil, err
}
b, ok := status.(*jetstream.KeyValueBucketStatus)
if !ok || b.StreamInfo() == nil {
return nil, fmt.Errorf("the bus answered no stream behind %s's state %s", module, name)
}
info := b.StreamInfo()
return &StateInfo{State: name, Bucket: status.Bucket(), Bytes: info.State.Bytes, Keys: uint64(info.State.NumSubjects),
MaxBytes: info.Config.MaxBytes, MaxValueBytes: info.Config.MaxMsgSize, History: status.History(),
TTLSeconds: int64(status.TTL() / time.Second), KeyTTL: info.Config.AllowMsgTTL && status.LimitMarkerTTL() > 0}, nil
}
// StatePut writes one key, as the module, where the module keeps the state. It answers the revision.
func (c *Conn) StatePut(module, name, key string, value json.RawMessage) (uint64, error) {
s, err := c.writable(module, name)