-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
feat(trace-tree-node): BaseNode implementation changes to achieve feature parity #101873
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: abdk/trace-tree-basenode-usage
Are you sure you want to change the base?
feat(trace-tree-node): BaseNode implementation changes to achieve feature parity #101873
Conversation
| for (const error of value.errors) { | ||
| this.parent.errors.add(error); | ||
| } | ||
| const closestEAPTransaction = this.findParentEapTransaction(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were propagating issues to the closest parent and not the closest transaction parent, like in the legacy trace tree node implementation.
| value.start_timestamp * 1e3, | ||
| (value.timestamp - value.start_timestamp) * 1e3, | ||
| ]; | ||
| if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adds the validation for value.timestamp used to initialize TransactioNode.space[1]. Safer, helps pass a bunch of tests in trace.spec.tsx
| transaction.parent = parent; | ||
| } | ||
|
|
||
| // Invalidating the node and its children to ensure the tree is rebuilt correctly, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block should run after all of the reparenting is done.
- Invalidates at the end, ensures that node depths and connectors lazily calculated at render, are accurate.
❌ 2 Tests Failed:
View the top 2 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
gggritso
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, just a few questions!
| return ( | ||
| <TraceSpanRow | ||
| {...props} | ||
| // Won't need this cast once we use BaseNode type for props.node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is stale now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spot on, I'll remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| get projectSlug(): string { | ||
| // The span value does not have a project slug, so we need to find a parent that has one. | ||
| // If we don't find one, we return the default project slug. | ||
| return this.findParent(p => !!p.projectSlug)?.projectSlug ?? 'default'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there guaranteed to be a parent with a project slug? I'm wondering if it makes sense to fetch project slugs from ProjectsStore instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gggritso Yeah, we always expect spans to be embedded under a transaction in the waterfall. Instead of looking for a transaction with a projectSlug, I look for a parent here to be more generic.
I don't fully get the ProjectsStore route 🤔 , re: a trace can have multiple projects, there's no projectID attached to spans to look for a specific project by
| findParentTransaction(): TransactionNode | null { | ||
| return this.findParent<TransactionNode>(p => isTransactionNode(p)); | ||
| } | ||
|
|
||
| findParentEapTransaction(): EapSpanNode | null { | ||
| return this.findParent<EapSpanNode>(p => isEAPTransactionNode(p)); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this possible to do without type guards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gggritso, I think that this is a good use case for a type guard. We are looking for a specific node in the base node class. The problem initially was that such type guards were scattered all over the place, we mitigated that quite a lot.
We can add is_transaction, is_eap_transaction, is_span... attrs to the baseNode classe but I don't really think that is any cleaner 🤔
We need methods like findParentTransaction if we are looking for a specific property that only exists in a TransactionNode type, like transaction id. The usage of the guard is now embedded in the baseNode instance so we can just do node.findParentTransaction instead of node.find(p => isTransactionNode(p)) which is an improvement.
Open to suggestions, lmk!
| this.transactionId === id || | ||
| hasMatchingErrors || | ||
| hasMatchingOccurrences | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Tree Traversal: A Performance Bottleneck
The matchById method calls this.transactionId, which triggers parent tree traversal via findParentTransaction() and findParentEapTransaction() on every invocation. When matchById is called repeatedly during tree searches, this creates expensive redundant parent traversals for nodes that don't override matchById, significantly impacting performance on large trace trees.
This PR includes the changes required in BaseNode and it's subclasses to achieve feature parity as we replace
TraceTreeNodewithBaseNodein the stacked PR: feat(trace-tree-node): Replacing legacy TraceTreeNode usage with new BaseNode class #101874Added tests for new BaseNode methods
Got rid of all typescript errors form BaseNode and its subclasses
Added in line PR comments for blocks that aren't trivial