§469 (GR, A-8 line of G): a bucket composed from an old state section takes its maximum size from its max-mib
The grants part's composer gains Bucket.MaxMiB and Bucket.MaxBytes() (as mesh-sdk's buscompose has them): the bucket's stream is created with that cap and an assertion raises a held one to it; an entry naming none keeps the mesh's cap, so no bucket of today changes. Builds: design 47 G §469, §695 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -5033,3 +5033,32 @@ func TestThePartNamesTheStreamItReadsWholeWaiting(t *testing.T) {
|
||||
t.Fatalf("after its whole read ended the streams are %+v, want it read", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestAnOldStateSectionDeclaresItsCap is design 47 G §469: a bucket composed from an old state section takes its maximum size from the
|
||||
// entry's `max-mib`, and one naming none keeps the mesh's cap, so no bucket of today changes.
|
||||
func TestAnOldStateSectionDeclaresItsCap(t *testing.T) {
|
||||
m, err := catalogue.Decode([]byte(`{"module":"mod-p","version":"1","state":[{"name":"pipelines","max-mib":256},"plain"]}`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := map[string]int64{"KV_mod-p_pipelines": 256 << 20, "KV_mod-p_plain": 0}
|
||||
got := map[string]int64{}
|
||||
for _, it := range grants.Composed(m, []string{"a"}) {
|
||||
if it.Kind == "bucket" {
|
||||
got[it.Stream] = it.Composed.MaxBytes
|
||||
}
|
||||
}
|
||||
if !maps.Equal(got, want) {
|
||||
t.Errorf("the composed buckets' caps = %v, want %v", got, want)
|
||||
}
|
||||
for name, max := range map[string]int{"pipelines": 256, "plain": 0} {
|
||||
cfg := buscompose.BucketStreamConfig(buscompose.Bucket{Module: "mod-p", Name: name, MaxMiB: max})
|
||||
wantBytes := int64(buscompose.StateMaxBytes)
|
||||
if max > 0 {
|
||||
wantBytes = int64(max) << 20
|
||||
}
|
||||
if cfg.MaxBytes != wantBytes {
|
||||
t.Errorf("%s is created with %d bytes as its maximum size, want %d", name, cfg.MaxBytes, wantBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ func BucketStreamConfig(b Bucket) jetstream.StreamConfig {
|
||||
AllowDirect: true,
|
||||
Discard: jetstream.DiscardNew,
|
||||
}
|
||||
// An old state section's entry names its own cap (design 47 G §469); one naming none keeps the mesh's.
|
||||
if max := b.MaxBytes(); max > 0 {
|
||||
cfg.MaxBytes = max
|
||||
}
|
||||
if b.KeyTTL {
|
||||
cfg.AllowMsgTTL, cfg.SubjectDeleteMarkerTTL = true, KeyTTLMarkerTTL
|
||||
}
|
||||
|
||||
@@ -48,6 +48,18 @@ type Bucket struct {
|
||||
// Whole is the bucket's name where it is not BucketName(Module, Name): one node's bucket of a state kept one bucket per
|
||||
// node, the node-engine's compositions `composed-<node>` (ADR 0593 §6, EngineComposedBuckets).
|
||||
Whole string
|
||||
// MaxMiB is the bucket's cap in MiB, from an old state section's `max-mib` (design 47 G §469); zero names none, and the bucket
|
||||
// keeps the mesh's cap (StateMaxBytes) as every bucket of today does.
|
||||
MaxMiB int
|
||||
}
|
||||
|
||||
// MaxBytes is the bucket's cap in bytes as the bus's maximum size, from its MaxMiB: -1 where it names none (buscompose.Bucket.MaxBytes
|
||||
// of mesh-sdk).
|
||||
func (b Bucket) MaxBytes() int64 {
|
||||
if b.MaxMiB <= 0 {
|
||||
return -1
|
||||
}
|
||||
return int64(b.MaxMiB) * 1024 * 1024
|
||||
}
|
||||
|
||||
// KeyTTLMarkerTTL is how long the marker an expired key leaves is kept: long enough for a watcher to hear it.
|
||||
|
||||
@@ -277,9 +277,12 @@ func Composed(m catalogue.Manifest, nodes []string) []Item {
|
||||
if per < 1 {
|
||||
per = 1
|
||||
}
|
||||
out = append(out, Item{Kind: "bucket", Stream: "KV_" + b.Bucket(), Composed: Limits{
|
||||
Subjects: []string{"$KV." + b.Bucket() + ".>"}, Retention: string(buscompose.RetentionLimits),
|
||||
MaxAgeHours: b.TTLSeconds / 3600, MaxPerSubject: per}})
|
||||
limits := Limits{Subjects: []string{"$KV." + b.Bucket() + ".>"}, Retention: string(buscompose.RetentionLimits),
|
||||
MaxAgeHours: b.TTLSeconds / 3600, MaxPerSubject: per}
|
||||
if max := b.MaxBytes(); max > 0 {
|
||||
limits.MaxBytes = max
|
||||
}
|
||||
out = append(out, Item{Kind: "bucket", Stream: "KV_" + b.Bucket(), Composed: limits})
|
||||
}
|
||||
for _, l := range logsOf(m) {
|
||||
c := l.Config()
|
||||
|
||||
@@ -308,7 +308,7 @@ func issuedTools(m catalogue.Manifest) []string {
|
||||
func bucketsOf(m catalogue.Manifest) []buscompose.Bucket {
|
||||
var out []buscompose.Bucket
|
||||
for _, s := range m.State {
|
||||
out = append(out, buscompose.Bucket{Module: m.Module, Name: s.Name, History: s.History, TTLSeconds: s.TTLSeconds,
|
||||
out = append(out, buscompose.Bucket{Module: m.Module, Name: s.Name, History: s.History, TTLSeconds: s.TTLSeconds, MaxMiB: s.MaxMiB,
|
||||
PerMachine: s.PerMachine, KeyTTL: s.KeyTTL, ReadOnly: s.ReadOnly})
|
||||
}
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user