Skip to content

Commit be565fd

Browse files
committed
fix(frontend/config): non-depth link selectors should not be fused after rejection
1 parent c10ddb0 commit be565fd

File tree

3 files changed

+48
-45
lines changed

3 files changed

+48
-45
lines changed

pkg/frontend/reader/merge/merge.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ func (fl *followLinkPool[M]) scheduleFrom(obj *object[M], followLimit *atomic.In
110110
parentKey, childKey, parentIsSource = link.Key, obj.key, false
111111
}
112112

113-
subSelector := linkSelector.Admit(parentKey, childKey, parentIsSource, link.Class)
114-
if subSelector != nil {
113+
isAdmitted, subSelector := linkSelector.Admit(parentKey, childKey, parentIsSource, link.Class)
114+
if isAdmitted {
115115
admittedLinks = append(admittedLinks, link)
116116
fl.knownKeys.Insert(link.Key)
117117
fl.schedule(link.Key, subSelector, followLimit, int32(fl.endTime.Sub(fl.startTime)/(time.Minute*30)))

pkg/frontend/tf/config/link_selector.go

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,19 @@ import utilobject "github.com/kubewharf/kelemetry/pkg/util/object"
1919
type LinkSelector interface {
2020
// Whether to follow the given link.
2121
//
22-
// If link should be followed, return a non-nil LinkSelector.
23-
// The returned object will be used to recursively follow links in the linked object.
24-
Admit(parent utilobject.Key, child utilobject.Key, parentIsSource bool, linkClass string) LinkSelector
22+
// The first output indicates whether the selector admits this link.
23+
// The second output is the selector state that transitive links should use for admission.
24+
// The second output may still be useful even if the first output is false when it is part of a UnionLinkSelector.
25+
// A nil state "fuses" the selector, i.e. always return false for further transitive links.
26+
Admit(parent utilobject.Key, child utilobject.Key, parentIsSource bool, linkClass string) (_admit bool, _nextState LinkSelector)
27+
}
28+
29+
func nilableLinkSelectorAdmit(selector LinkSelector, parent utilobject.Key, child utilobject.Key, parentIsSource bool, linkClass string) (bool, LinkSelector) {
30+
if selector == nil {
31+
return false, nil
32+
}
33+
34+
return selector.Admit(parent, child, parentIsSource, linkClass)
2535
}
2636

2737
type ConstantLinkSelector bool
@@ -31,12 +41,12 @@ func (selector ConstantLinkSelector) Admit(
3141
child utilobject.Key,
3242
parentIsSource bool,
3343
linkClass string,
34-
) LinkSelector {
44+
) (_admit bool, _nextState LinkSelector) {
3545
if selector {
36-
return selector
46+
return true, selector
3747
}
3848

39-
return nil
49+
return false, selector
4050
}
4151

4252
type IntersectLinkSelector []LinkSelector
@@ -46,17 +56,17 @@ func (selector IntersectLinkSelector) Admit(
4656
childKey utilobject.Key,
4757
parentIsSource bool,
4858
linkClass string,
49-
) LinkSelector {
50-
newChildren := make([]LinkSelector, len(selector))
51-
52-
for i, child := range selector {
53-
newChildren[i] = child.Admit(parentKey, childKey, parentIsSource, linkClass)
54-
if newChildren[i] == nil {
55-
return nil
56-
}
59+
) (_admit bool, _nextState LinkSelector) {
60+
admit := true
61+
nextMemberStates := make([]LinkSelector, len(selector))
62+
63+
for i, member := range selector {
64+
memberAdmit, nextMemberState := nilableLinkSelectorAdmit(member, parentKey, childKey, parentIsSource, linkClass)
65+
admit = admit && memberAdmit
66+
nextMemberStates[i] = nextMemberState
5767
}
5868

59-
return IntersectLinkSelector(newChildren)
69+
return admit, IntersectLinkSelector(nextMemberStates)
6070
}
6171

6272
type UnionLinkSelector []LinkSelector
@@ -66,22 +76,15 @@ func (selector UnionLinkSelector) Admit(
6676
childKey utilobject.Key,
6777
parentIsSource bool,
6878
linkClass string,
69-
) LinkSelector {
70-
newChildren := make([]LinkSelector, len(selector))
71-
72-
ok := false
73-
for i, child := range selector {
74-
if child != nil {
75-
newChildren[i] = child.Admit(parentKey, childKey, parentIsSource, linkClass)
76-
if newChildren[i] != nil {
77-
ok = true
78-
}
79-
}
80-
}
79+
) (_admit bool, _nextState LinkSelector) {
80+
admit := false
81+
nextMemberStates := make([]LinkSelector, len(selector))
8182

82-
if ok {
83-
return UnionLinkSelector(newChildren)
83+
for i, member := range selector {
84+
memberAdmit, nextMemberState := nilableLinkSelectorAdmit(member, parentKey, childKey, parentIsSource, linkClass)
85+
admit = admit || memberAdmit
86+
nextMemberStates[i] = nextMemberState
8487
}
8588

86-
return nil
89+
return admit, UnionLinkSelector(nextMemberStates)
8790
}

pkg/frontend/tf/defaults/modifier/link_selector.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,29 +146,27 @@ func (s denySiblingsLinkSelector) Admit(
146146
child utilobject.Key,
147147
isFromParent bool,
148148
linkClass string,
149-
) tfconfig.LinkSelector {
149+
) (_admit bool, _nextState tfconfig.LinkSelector) {
150150
if !s.hasFirst {
151-
return denySiblingsLinkSelector{hasFirst: true, firstIsFromParent: isFromParent}
151+
return true, denySiblingsLinkSelector{hasFirst: true, firstIsFromParent: isFromParent}
152152
}
153-
if s.firstIsFromParent != isFromParent {
154-
return nil
155-
}
156-
return s
153+
154+
return s.firstIsFromParent == isFromParent, s
157155
}
158156

159157
// The path from queried object to any other object in the tree must only contain links matching this pattern.
160158
type patternLinkSelector struct {
161159
patterns []LinkPattern
162160
}
163161

164-
func (s patternLinkSelector) Admit(parent utilobject.Key, child utilobject.Key, isFromParent bool, linkClass string) tfconfig.LinkSelector {
162+
func (s patternLinkSelector) Admit(parent utilobject.Key, child utilobject.Key, isFromParent bool, linkClass string) (_admit bool, _nextState tfconfig.LinkSelector) {
165163
for _, pattern := range s.patterns {
166164
if !pattern.Matches(parent, child, isFromParent, linkClass) {
167-
return nil
165+
return false, s
168166
}
169167
}
170168

171-
return s
169+
return true, s
172170
}
173171

174172
type direction bool
@@ -189,14 +187,16 @@ func (d directedDistanceLinkSelector) Admit(
189187
child utilobject.Key,
190188
isFromParent bool,
191189
linkClass string,
192-
) tfconfig.LinkSelector {
190+
) (_admit bool, _nextState tfconfig.LinkSelector) {
193191
if isFromParent != (d.direction == directionDownwards) {
194-
return d
192+
return true, d
195193
}
194+
196195
if d.distance == 0 {
197-
return nil
196+
return false, nil
198197
}
199-
return directedDistanceLinkSelector{
198+
199+
return true, directedDistanceLinkSelector{
200200
direction: d.direction,
201201
distance: d.distance - 1,
202202
}

0 commit comments

Comments
 (0)