Check projection budgets before container allocation

This commit is contained in:
2026-10-25 21:25:00 +00:00
parent ae3408a096
commit ea27f17f5c
4 changed files with 130 additions and 6 deletions

View File

@@ -27,11 +27,12 @@ type valueVisit struct {
// valueOperation owns one traversal's cycle and budget state and reuses the
// current load's descriptor cache for dynamic values.
type valueOperation struct {
cloneMode secretCloneMode
schema *schemaDescriptor
limits projectionLimits
active map[valueVisit]bool
nodes int
cloneMode secretCloneMode
schema *schemaDescriptor
limits projectionLimits
active map[valueVisit]bool
nodes int
nodeCredits int
}
func (o *valueOperation) dynamicDescriptor(current reflect.Type, path Path) (*typeDescriptor, *projectionIssue) {
@@ -72,7 +73,18 @@ func descriptorContainsSecret(descriptor *typeDescriptor, visited map[*typeDescr
func (o *valueOperation) charge(path Path) *projectionIssue {
o.nodes++
if o.limits.nodes >= 0 && o.nodes > o.limits.nodes {
if o.limits.nodes >= 0 && o.nodes-o.nodeCredits > o.limits.nodes {
return &projectionIssue{code: CodeSchemaProjectionLimit, path: path.clone(), message: "configuration projection exceeds the node limit"}
}
return nil
}
func (o *valueOperation) checkMinimumChildren(path Path, count, nodesPerChild int) *projectionIssue {
if o.limits.nodes < 0 {
return nil
}
remaining := o.limits.nodes - (o.nodes - o.nodeCredits)
if remaining < 0 || count > remaining/nodesPerChild {
return &projectionIssue{code: CodeSchemaProjectionLimit, path: path.clone(), message: "configuration projection exceeds the node limit"}
}
return nil