Skip to content

Commit

Permalink
feat: update reference to matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
xnanodax committed Dec 17, 2024
1 parent 2804c8e commit abab16e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 24 deletions.
23 changes: 11 additions & 12 deletions src/v3/ActiveTrace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ export class TraceStateMachine<
continue
}

const matcher = this.context.definition.requiredSpans[i]!
if (matcher(spanAndAnnotation, this.context)) {
const doesSpanMatch = this.context.definition.requiredSpans[i]!
if (doesSpanMatch(spanAndAnnotation, this.context)) {
// remove the index of this definition from the list of requiredToEnd
this.context.requiredToEndIndexChecklist.delete(i)

Expand Down Expand Up @@ -389,11 +389,10 @@ export class TraceStateMachine<
span: { ...span, isIdle: true },
}
if (idleRegressionCheckSpan) {
for (const matcher of this.context.definition.requiredSpans) {
for (const doesSpanMatch of this.context.definition.requiredSpans) {
if (
// v3 TODO: rename matcher in the whole file to 'doesSpanMatch' -> Cynthia
matcher(idleRegressionCheckSpan, this.context) &&
matcher.isIdle
doesSpanMatch(idleRegressionCheckSpan, this.context) &&
doesSpanMatch.isIdle
) {
// check if we regressed on "isIdle", and if so, transition to interrupted with reason
return {
Expand All @@ -408,8 +407,8 @@ export class TraceStateMachine<

// does span satisfy any of the "debouncedOn" and if so, restart our debounce timer
if (this.context.definition.debounceOn) {
for (const matcher of this.context.definition.debounceOn) {
if (matcher(spanAndAnnotation, this.context)) {
for (const doesSpanMatch of this.context.definition.debounceOn) {
if (doesSpanMatch(spanAndAnnotation, this.context)) {
// Sometimes spans are processed out of order, we update the lastRelevant if this span ends later
if (
spanAndAnnotation.annotation.operationRelativeEndTime >
Expand Down Expand Up @@ -629,8 +628,8 @@ export class TraceStateMachine<
// if the entry matches any of the interruptOn criteria,
// transition to complete state with the 'matched-on-interrupt' interruptionReason
if (this.context.definition.interruptOn) {
for (const matcher of this.context.definition.interruptOn) {
if (matcher(spanAndAnnotation, this.context)) {
for (const doesSpanMatch of this.context.definition.interruptOn) {
if (doesSpanMatch(spanAndAnnotation, this.context)) {
return {
transitionToState: 'complete',
interruptionReason: 'matched-on-interrupt',
Expand Down Expand Up @@ -907,8 +906,8 @@ export class ActiveTrace<
if (!this.definition.labelMatching) return labels

Object.entries(this.definition.labelMatching).forEach(
([label, matcher]) => {
if (matcher(span, context)) {
([label, doesSpanMatch]) => {
if (doesSpanMatch(span, context)) {
labels.push(label)
}
},
Expand Down
34 changes: 22 additions & 12 deletions src/v3/recordingComputeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ export function getComputedValues<
for (const definition of traceDefinition.computedValueDefinitions) {
const { name, matches, computeValueFromMatches } = definition

// Initialize arrays to hold matches for each matcher
// Initialize arrays to hold matches for each doesSpanMatch matcher
const matchingEntriesByMatcher: SpanAndAnnotation<AllPossibleScopesT>[][] =
Array.from({ length: matches.length }, () => [])

// Single pass through recordedItems
for (const item of recordedItems) {
matches.forEach((matcher, index) => {
if (matcher(item, { input, definition: traceDefinition })) {
matches.forEach((doesSpanMatch, index) => {
if (doesSpanMatch(item, { input, definition: traceDefinition })) {
matchingEntriesByMatcher[index]!.push(item)
}
})
Expand Down Expand Up @@ -153,7 +153,6 @@ export function getComputedSpans<

return computedSpans
}

function getComputedRenderBeaconSpans<
TracerScopeKeysT extends KeysOfUnion<AllPossibleScopesT>,
AllPossibleScopesT,
Expand All @@ -175,6 +174,7 @@ function getComputedRenderBeaconSpans<
firstContentStart: number | undefined
renderCount: number
sumOfDurations: number
lastRenderStartTime: number | undefined // Track the last render start time
}
>()

Expand All @@ -186,19 +186,18 @@ function getComputedRenderBeaconSpans<
entry.span.type !== 'component-render' &&
entry.span.type !== 'component-render-start'
) {
// need to look at component-render-start too, because react might discard some renders as optimization
// ratio of component-render-start to component-render isn't always 1:1
continue
}
const { name, startTime, duration, scope, renderedOutput } = entry.span
// accept any span that either matches scope or doesn't share any of the scope values

const scopeMatch = scopeKeys.every(
(key) =>
(scope as PossibleScopeObject | undefined)?.[key] === undefined ||
(input.scope as PossibleScopeObject)[key] ===
(scope as PossibleScopeObject)[key],
)
if (!scopeMatch) continue

const start = startTime.now
const contentfulRenderEnd =
entry.span.type === 'component-render' && renderedOutput === 'content'
Expand All @@ -207,8 +206,6 @@ function getComputedRenderBeaconSpans<

const spanTimes = renderSpansByBeacon.get(name)

// v3 TODO: make sure that sumOfRenderDurations takes into account that mismatch between render-start and full render - might be discarded and re-render - should extend the first render duration from the first render start to the first end

if (!spanTimes) {
renderSpansByBeacon.set(name, {
firstStart: start,
Expand All @@ -220,17 +217,30 @@ function getComputedRenderBeaconSpans<
entry.span.type === 'component-render' && renderedOutput === 'loading'
? start + duration
: undefined,
lastRenderStartTime:
entry.span.type === 'component-render-start' ? start : undefined,
})
} else {
spanTimes.firstStart = Math.min(spanTimes.firstStart, start)
spanTimes.firstContentfulRenderEnd =
contentfulRenderEnd && spanTimes.firstContentfulRenderEnd
? Math.min(spanTimes.firstContentfulRenderEnd, contentfulRenderEnd)
: contentfulRenderEnd ?? spanTimes.firstContentfulRenderEnd

if (entry.span.type === 'component-render') {
spanTimes.renderCount += 1
// If there was a pending render start, include the time from that start to this render
if (spanTimes.lastRenderStartTime !== undefined) {
spanTimes.sumOfDurations +=
start + duration - spanTimes.lastRenderStartTime
spanTimes.lastRenderStartTime = undefined
} else {
spanTimes.sumOfDurations += duration
}
} else if (entry.span.type === 'component-render-start') {
spanTimes.lastRenderStartTime = start
}
spanTimes.sumOfDurations += duration

if (
spanTimes.firstContentStart === undefined &&
renderedOutput === 'content'
Expand Down Expand Up @@ -301,8 +311,8 @@ export function createTraceRecording<
const anyNonSuppressedErrors = recordedItems.some(
(spanAndAnnotation) =>
spanAndAnnotation.span.status === 'error' &&
!definition.suppressErrorStatusPropagationOn?.some((matcher) =>
matcher(spanAndAnnotation, data),
!definition.suppressErrorStatusPropagationOn?.some((doesSpanMatch) =>
doesSpanMatch(spanAndAnnotation, data),
),
)

Expand Down

0 comments on commit abab16e

Please sign in to comment.