Skip to content

Commit abe9a7b

Browse files
committed
Update max location calculation
1 parent 69a72d3 commit abe9a7b

File tree

1 file changed

+65
-13
lines changed

1 file changed

+65
-13
lines changed

internal/controller/nginx/config/servers.go

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -762,27 +762,79 @@ func needsInternalLocationsForMatches(rule dataplane.PathRule) bool {
762762
// for example, {/foo: {exact: {}, prefix: {}}}.
763763
type pathAndTypeMap map[string]map[dataplane.PathType]struct{}
764764

765-
// To calculate the maximum number of locations, we need to take into account the following:
766-
// 1. Each match rule for a path rule will have one location.
767-
// 2. Each path rule may have an additional location if it contains non-path-only matches.
768-
// 3. Each prefix path rule may have an additional location if it doesn't contain trailing slash.
769-
// 4. There may be an additional location for the default root path.
770-
// 5. There may be an additional location per parent location for the inference extension.
771-
// We also return a map of all paths and their types.
772765
func getMaxLocationCountAndPathMap(pathRules []dataplane.PathRule) (int, pathAndTypeMap) {
773-
maxLocs := 1
766+
// To calculate the maximum number of locations, we need to take into account the following:
767+
// 1. Each path rule will have at least one external location.
768+
// 2. Each path rule may have an additional external location if it's a non-slashed prefix path.
769+
// 3. There may be an additional location for the default root path.
770+
// 4. For inference backends:
771+
// - Single backend without matches: 2 locations (external EPP + internal proxy pass)
772+
// - Single backend with matches: 3 locations (external redirect + internal EPP + internal proxy pass)
773+
// - Multiple backends without matches: 1 external + (2 * numBackends) internal locations
774+
// - Multiple backends with matches: 1 external + 1 split clients + (2 * numBackends) internal locations
775+
// 5. For non-inference backends with matches:
776+
// - Each match rule gets an internal location
777+
// We also return a map of all paths and their types.
778+
779+
maxLocs := 0
774780
pathsAndTypes := make(pathAndTypeMap)
781+
775782
for _, rule := range pathRules {
776-
maxLocs += (len(rule.MatchRules) * 2) + 2
783+
// External locations calculation
784+
maxLocs++ // Base external location for the path
785+
786+
// Add the path to the map
777787
if pathsAndTypes[rule.Path] == nil {
778-
pathsAndTypes[rule.Path] = map[dataplane.PathType]struct{}{
779-
rule.PathType: {},
788+
pathsAndTypes[rule.Path] = make(map[dataplane.PathType]struct{})
789+
}
790+
pathsAndTypes[rule.Path][rule.PathType] = struct{}{}
791+
792+
// Check if we need an additional external location for non-slashed prefix paths
793+
if isNonSlashedPrefixPath(rule.PathType, rule.Path) {
794+
maxLocs++ // Additional external location for exact match
795+
}
796+
797+
// Determine if we need internal locations for matches
798+
needsInternalMatches := needsInternalLocationsForMatches(rule)
799+
800+
// Internal locations calculation
801+
for _, matchRule := range rule.MatchRules {
802+
if !rule.HasInferenceBackends {
803+
// Non-inference backends with matches need internal locations
804+
if needsInternalMatches {
805+
maxLocs++ // Internal match location per match rule
806+
}
807+
} else {
808+
// Inference backends calculation
809+
numBackends := len(matchRule.BackendGroup.Backends)
810+
811+
if needsInternalMatches {
812+
// Has HTTP matching conditions
813+
if numBackends > 1 {
814+
// Multiple backends with matches: split clients + 2 locations per backend
815+
maxLocs++ // Internal split clients location
816+
maxLocs += numBackends * 2 // EPP + proxy pass per backend
817+
} else {
818+
// Single backend with matches: EPP + proxy pass
819+
maxLocs += 2
820+
}
821+
} else {
822+
// No HTTP matching conditions
823+
if numBackends > 1 {
824+
// Multiple backends without matches: 2 locations per backend (no split clients for external)
825+
maxLocs += numBackends * 2 // EPP + proxy pass per backend
826+
} else {
827+
// Single backend without matches: proxy pass only (external becomes EPP)
828+
maxLocs++ // Just the internal proxy pass location
829+
}
830+
}
780831
}
781-
} else {
782-
pathsAndTypes[rule.Path][rule.PathType] = struct{}{}
783832
}
784833
}
785834

835+
// Add 1 for potential default root location
836+
maxLocs++
837+
786838
return maxLocs, pathsAndTypes
787839
}
788840

0 commit comments

Comments
 (0)