Skip to content

Commit

Permalink
fix(frontend/config): non-depth link selectors should not be fused af…
Browse files Browse the repository at this point in the history
…ter rejection
  • Loading branch information
SOF3 committed Dec 5, 2023
1 parent c10ddb0 commit be565fd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 45 deletions.
4 changes: 2 additions & 2 deletions pkg/frontend/reader/merge/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ func (fl *followLinkPool[M]) scheduleFrom(obj *object[M], followLimit *atomic.In
parentKey, childKey, parentIsSource = link.Key, obj.key, false
}

subSelector := linkSelector.Admit(parentKey, childKey, parentIsSource, link.Class)
if subSelector != nil {
isAdmitted, subSelector := linkSelector.Admit(parentKey, childKey, parentIsSource, link.Class)
if isAdmitted {
admittedLinks = append(admittedLinks, link)
fl.knownKeys.Insert(link.Key)
fl.schedule(link.Key, subSelector, followLimit, int32(fl.endTime.Sub(fl.startTime)/(time.Minute*30)))
Expand Down
63 changes: 33 additions & 30 deletions pkg/frontend/tf/config/link_selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,19 @@ import utilobject "github.com/kubewharf/kelemetry/pkg/util/object"
type LinkSelector interface {
// Whether to follow the given link.
//
// If link should be followed, return a non-nil LinkSelector.
// The returned object will be used to recursively follow links in the linked object.
Admit(parent utilobject.Key, child utilobject.Key, parentIsSource bool, linkClass string) LinkSelector
// The first output indicates whether the selector admits this link.
// The second output is the selector state that transitive links should use for admission.
// The second output may still be useful even if the first output is false when it is part of a UnionLinkSelector.
// A nil state "fuses" the selector, i.e. always return false for further transitive links.
Admit(parent utilobject.Key, child utilobject.Key, parentIsSource bool, linkClass string) (_admit bool, _nextState LinkSelector)
}

func nilableLinkSelectorAdmit(selector LinkSelector, parent utilobject.Key, child utilobject.Key, parentIsSource bool, linkClass string) (bool, LinkSelector) {

Check failure on line 29 in pkg/frontend/tf/config/link_selector.go

View workflow job for this annotation

GitHub Actions / golangci-lint

line is 159 characters (lll)
if selector == nil {
return false, nil
}

return selector.Admit(parent, child, parentIsSource, linkClass)
}

type ConstantLinkSelector bool
Expand All @@ -31,12 +41,12 @@ func (selector ConstantLinkSelector) Admit(
child utilobject.Key,
parentIsSource bool,
linkClass string,
) LinkSelector {
) (_admit bool, _nextState LinkSelector) {
if selector {
return selector
return true, selector
}

return nil
return false, selector
}

type IntersectLinkSelector []LinkSelector
Expand All @@ -46,17 +56,17 @@ func (selector IntersectLinkSelector) Admit(
childKey utilobject.Key,
parentIsSource bool,
linkClass string,
) LinkSelector {
newChildren := make([]LinkSelector, len(selector))

for i, child := range selector {
newChildren[i] = child.Admit(parentKey, childKey, parentIsSource, linkClass)
if newChildren[i] == nil {
return nil
}
) (_admit bool, _nextState LinkSelector) {
admit := true
nextMemberStates := make([]LinkSelector, len(selector))

for i, member := range selector {
memberAdmit, nextMemberState := nilableLinkSelectorAdmit(member, parentKey, childKey, parentIsSource, linkClass)
admit = admit && memberAdmit
nextMemberStates[i] = nextMemberState
}

return IntersectLinkSelector(newChildren)
return admit, IntersectLinkSelector(nextMemberStates)
}

type UnionLinkSelector []LinkSelector
Expand All @@ -66,22 +76,15 @@ func (selector UnionLinkSelector) Admit(
childKey utilobject.Key,
parentIsSource bool,
linkClass string,
) LinkSelector {
newChildren := make([]LinkSelector, len(selector))

ok := false
for i, child := range selector {
if child != nil {
newChildren[i] = child.Admit(parentKey, childKey, parentIsSource, linkClass)
if newChildren[i] != nil {
ok = true
}
}
}
) (_admit bool, _nextState LinkSelector) {
admit := false
nextMemberStates := make([]LinkSelector, len(selector))

if ok {
return UnionLinkSelector(newChildren)
for i, member := range selector {
memberAdmit, nextMemberState := nilableLinkSelectorAdmit(member, parentKey, childKey, parentIsSource, linkClass)
admit = admit || memberAdmit
nextMemberStates[i] = nextMemberState
}

return nil
return admit, UnionLinkSelector(nextMemberStates)
}
26 changes: 13 additions & 13 deletions pkg/frontend/tf/defaults/modifier/link_selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,29 +146,27 @@ func (s denySiblingsLinkSelector) Admit(
child utilobject.Key,
isFromParent bool,
linkClass string,
) tfconfig.LinkSelector {
) (_admit bool, _nextState tfconfig.LinkSelector) {
if !s.hasFirst {
return denySiblingsLinkSelector{hasFirst: true, firstIsFromParent: isFromParent}
return true, denySiblingsLinkSelector{hasFirst: true, firstIsFromParent: isFromParent}
}
if s.firstIsFromParent != isFromParent {
return nil
}
return s

return s.firstIsFromParent == isFromParent, s
}

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

func (s patternLinkSelector) Admit(parent utilobject.Key, child utilobject.Key, isFromParent bool, linkClass string) tfconfig.LinkSelector {
func (s patternLinkSelector) Admit(parent utilobject.Key, child utilobject.Key, isFromParent bool, linkClass string) (_admit bool, _nextState tfconfig.LinkSelector) {

Check failure on line 162 in pkg/frontend/tf/defaults/modifier/link_selector.go

View workflow job for this annotation

GitHub Actions / golangci-lint

line is 166 characters (lll)
for _, pattern := range s.patterns {
if !pattern.Matches(parent, child, isFromParent, linkClass) {
return nil
return false, s
}
}

return s
return true, s
}

type direction bool
Expand All @@ -189,14 +187,16 @@ func (d directedDistanceLinkSelector) Admit(
child utilobject.Key,
isFromParent bool,
linkClass string,
) tfconfig.LinkSelector {
) (_admit bool, _nextState tfconfig.LinkSelector) {
if isFromParent != (d.direction == directionDownwards) {
return d
return true, d
}

if d.distance == 0 {
return nil
return false, nil
}
return directedDistanceLinkSelector{

return true, directedDistanceLinkSelector{
direction: d.direction,
distance: d.distance - 1,
}
Expand Down

0 comments on commit be565fd

Please sign in to comment.