From 37cc17e5dca8d7228fb38e87be9c9939cd1525a6 Mon Sep 17 00:00:00 2001 From: Tim Sweeney Date: Tue, 4 Mar 2025 04:27:44 -0800 Subject: [PATCH] a lot of progress --- .../TraceNavigator/TraceNavigator.tsx | 34 +++--- .../TraceScrubber/components/scrubbers.ts | 24 +++++ .../TraceNavigator/TraceScrubber/index.tsx | 9 +- .../TraceNavigator/TraceViews/CodeView.tsx | 102 ++++++++---------- .../TraceNavigator/traceViewRegistry.ts | 5 +- 5 files changed, 98 insertions(+), 76 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceNavigator.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceNavigator.tsx index 18fd56b5af7c..975b0c95652d 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceNavigator.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceNavigator.tsx @@ -95,24 +95,28 @@ export const TraceNavigatorInner: FC = props => {

Trace View

{traceViews.map(view => { - const isDisabled = !!(view.maxTraces && traceCount > view.maxTraces); - const tooltipContent = isDisabled + const isDisabled = !!( + view.maxTraces && traceCount > view.maxTraces + ); + const tooltipContent = isDisabled ? `${view.label} view is disabled (maximum ${view.maxTraces} traces)` : view.label; - + return ( - setTraceViewId(view.id)} - icon={view.icon} - size="small" - className="!p-3" - disabled={isDisabled}> - {view.label} - }> - - - + setTraceViewId(view.id)} + icon={view.icon} + size="small" + className="!p-3" + disabled={isDisabled}> + {view.label} + + }> ); })}
diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/components/scrubbers.ts b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/components/scrubbers.ts index 0ae5bb7b438f..87dc516bd3cd 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/components/scrubbers.ts +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/components/scrubbers.ts @@ -1,3 +1,8 @@ +import { + getSortedPeerPathCallIds, + locateNodeForCallId, +} from '../../TraceViews/CodeView'; +import {buildCodeMap} from '../../TraceViews/utils'; import {createScrubber} from './BaseScrubber'; export const TimelineScrubber = createScrubber({ @@ -34,6 +39,25 @@ export const PeerScrubber = createScrubber({ }, }); +export const CodePathScrubber = createScrubber({ + label: 'Code Path', + description: + 'Navigate through all calls with the same code path as the selected call', + getNodes: ({traceTreeFlat, selectedCallId}) => { + if (!selectedCallId) { + return []; + } + const currentNode = traceTreeFlat[selectedCallId]; + if (!currentNode) { + return []; + } + + const codeMap = buildCodeMap(traceTreeFlat); + const codeNode = locateNodeForCallId(codeMap, selectedCallId); + return getSortedPeerPathCallIds(codeNode, traceTreeFlat); + }, +}); + export const SiblingScrubber = createScrubber({ label: 'Siblings', description: diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/index.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/index.tsx index e7bbe869179f..711e9035f939 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/index.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceScrubber/index.tsx @@ -2,6 +2,7 @@ import React from 'react'; import {BaseScrubberProps} from './components/BaseScrubber'; import { + CodePathScrubber, PeerScrubber, SiblingScrubber, StackScrubber, @@ -9,7 +10,12 @@ import { } from './components/scrubbers'; import {Container} from './styles'; -export type ScrubberOption = 'timeline' | 'peer' | 'sibling' | 'stack'; +export type ScrubberOption = + | 'timeline' + | 'peer' + | 'sibling' + | 'stack' + | 'codePath'; const TraceScrubber: React.FC< BaseScrubberProps & { @@ -26,6 +32,7 @@ const TraceScrubber: React.FC< {showScrubber('timeline') && } {showScrubber('peer') && } + {showScrubber('codePath') && } {showScrubber('sibling') && } {showScrubber('stack') && } diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceViews/CodeView.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceViews/CodeView.tsx index 85f2b3b0c10b..445242c26c62 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceViews/CodeView.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/TraceViews/CodeView.tsx @@ -1,8 +1,8 @@ -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useMemo} from 'react'; import styled from 'styled-components'; import {TreeView} from './TreeView'; -import {TraceViewProps} from './types'; +import {TraceTreeFlat, TraceViewProps} from './types'; import {buildCodeMap, CodeMapNode} from './utils'; import {formatDuration} from './utils'; @@ -96,18 +96,13 @@ const RecursionBlock = styled.div` interface CodeMapNodeProps extends TraceViewProps { node: CodeMapNode; - selectedOpName?: string; - onCallSelect: (callId: string) => void; - onOpSelect: (opName: string) => void; level?: number; } const CodeMapNodeComponent: React.FC = ({ node, selectedCallId, - selectedOpName, onCallSelect, - onOpSelect, traceTreeFlat, stack, level = 0, @@ -159,7 +154,6 @@ const CodeMapNodeComponent: React.FC = ({ const handleClick = (e: React.MouseEvent) => { e.preventDefault(); - onOpSelect(node.opName); // Select the first call in this operation if we have any calls if (node.callIds.length > 0) { @@ -208,9 +202,7 @@ const CodeMapNodeComponent: React.FC = ({ key={child.opName} node={child} selectedCallId={selectedCallId} - selectedOpName={selectedOpName} onCallSelect={onCallSelect} - onOpSelect={onOpSelect} traceTreeFlat={traceTreeFlat} stack={stack} level={level + 1} @@ -225,6 +217,36 @@ const CodeMapNodeComponent: React.FC = ({ ); }; +export const locateNodeForCallId = ( + codeMap: CodeMapNode[], + selectedCallId: string +) => { + const findOpByCallId = (nodes: CodeMapNode[]): CodeMapNode | null => { + for (const node of nodes) { + if (node.callIds.includes(selectedCallId)) { + return node; + } + const found = findOpByCallId(node.children); + if (found) { + return found; + } + } + return null; + }; + return findOpByCallId(codeMap); +}; + +export const getSortedPeerPathCallIds = ( + selectedCodeNode: CodeMapNode | null, + traceTreeFlat: TraceTreeFlat +) => { + return (selectedCodeNode?.callIds ?? []).sort( + (a, b) => + Date.parse(traceTreeFlat[a].call.started_at) - + Date.parse(traceTreeFlat[b].call.started_at) + ); +}; + export const CodeView: React.FC = ({ traceTreeFlat, selectedCallId, @@ -232,55 +254,19 @@ export const CodeView: React.FC = ({ stack, }) => { const codeMap = useMemo(() => buildCodeMap(traceTreeFlat), [traceTreeFlat]); - const [selectedOpName, setSelectedOpName] = useState(); // Find the selected operation's calls and update when selectedCallId changes - const selectedOp = useMemo(() => { + const selectedCodeNode = useMemo(() => { // First try to find the op containing the selected call - if (selectedCallId) { - const findOpByCallId = (nodes: CodeMapNode[]): CodeMapNode | null => { - for (const node of nodes) { - if (node.callIds.includes(selectedCallId)) { - return node; - } - const found = findOpByCallId(node.children); - if (found) { - return found; - } - } - return null; - }; - const opWithCall = findOpByCallId(codeMap); - if (opWithCall) { - return opWithCall; - } - } - - // Fall back to currently selected op - if (!selectedOpName) { + if (!selectedCallId) { return null; } - const findOp = (nodes: CodeMapNode[]): CodeMapNode | null => { - for (const node of nodes) { - if (node.opName === selectedOpName) { - return node; - } - const found = findOp(node.children); - if (found) { - return found; - } - } - return null; - }; - return findOp(codeMap); - }, [codeMap, selectedCallId, selectedOpName]); + return locateNodeForCallId(codeMap, selectedCallId); + }, [codeMap, selectedCallId]); - // Update selectedOpName when we find the operation containing selectedCallId - useEffect(() => { - if (selectedOp && selectedOp.opName !== selectedOpName) { - setSelectedOpName(selectedOp.opName); - } - }, [selectedOp, selectedOpName]); + const selectedPeerPathCallIds = useMemo(() => { + return getSortedPeerPathCallIds(selectedCodeNode, traceTreeFlat); + }, [selectedCodeNode, traceTreeFlat]); return ( @@ -290,9 +276,7 @@ export const CodeView: React.FC = ({ key={node.opName} node={node} selectedCallId={selectedCallId} - selectedOpName={selectedOpName} onCallSelect={onCallSelect} - onOpSelect={setSelectedOpName} traceTreeFlat={traceTreeFlat} stack={stack} /> @@ -300,11 +284,11 @@ export const CodeView: React.FC = ({ - {selectedOp ? ( + {selectedCodeNode ? ( <> - Calls for {selectedOp.opName} - {selectedOp.callIds.length} calls + Calls for {selectedCodeNode.opName} + {selectedPeerPathCallIds.length} calls
@@ -312,7 +296,7 @@ export const CodeView: React.FC = ({ traceTreeFlat={traceTreeFlat} selectedCallId={selectedCallId} onCallSelect={onCallSelect} - filterCallIds={selectedOp.callIds} + filterCallIds={selectedPeerPathCallIds} stack={stack} />
diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/traceViewRegistry.ts b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/traceViewRegistry.ts index 256278020abf..5fa1313cefc5 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/traceViewRegistry.ts +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/components/TraceNavigator/traceViewRegistry.ts @@ -38,13 +38,14 @@ export const traceViews: TraceViewRegistry = [ label: 'Tree', icon: 'layout-tabs', component: TreeView, + allowedScrubbers: ['timeline', 'peer', 'sibling', 'stack'], }, { id: 'code', label: 'Code', icon: 'code-alt', component: CodeView, - allowedScrubbers: ['peer'], + allowedScrubbers: ['codePath'], }, { id: 'flamegraph', @@ -52,6 +53,7 @@ export const traceViews: TraceViewRegistry = [ icon: 'chart-horizontal-bars', component: FlameGraphView, maxTraces: 500, + allowedScrubbers: ['timeline', 'peer', 'sibling', 'stack'], }, { id: 'graph', @@ -59,5 +61,6 @@ export const traceViews: TraceViewRegistry = [ icon: 'chart-scatterplot', component: GraphView, maxTraces: 50, + allowedScrubbers: ['timeline', 'peer', 'sibling', 'stack'], }, ];