Migrate framework events backing data structure to datasource
Summary: This will allow us to build a nice table easily. Reviewed By: lblasa Differential Revision: D47520029 fbshipit-source-id: 3cdd776533b66688329171eb29b892e0b9153540
This commit is contained in:
committed by
Facebook GitHub Bot
parent
16480a95f3
commit
7812dae764
@@ -17,14 +17,12 @@ import {
|
||||
} from '../types';
|
||||
import React, {useMemo} from 'react';
|
||||
import {
|
||||
Atom,
|
||||
DataInspector,
|
||||
DataSource,
|
||||
DataTable,
|
||||
DataTableColumn,
|
||||
DetailSidebar,
|
||||
Layout,
|
||||
useValue,
|
||||
} from 'flipper-plugin';
|
||||
|
||||
export function PerfStats(props: {
|
||||
@@ -32,15 +30,13 @@ export function PerfStats(props: {
|
||||
nodes: Map<Id, UINode>;
|
||||
rootId?: Id;
|
||||
events: DataSource<DynamicPerformanceStatsEvent, number>;
|
||||
frameworkEvents: Atom<Map<Id, FrameworkEvent[]>>;
|
||||
frameworkEvents: DataSource<FrameworkEvent>;
|
||||
}) {
|
||||
const uiStateValues = Object.entries(props.uiState).map(([key, value]) => [
|
||||
key,
|
||||
value.get(),
|
||||
]);
|
||||
|
||||
const frameworkEventsValue = useValue(props.frameworkEvents);
|
||||
|
||||
const allColumns = useMemo(() => {
|
||||
if (props.events.size > 0) {
|
||||
const row = props.events.get(0);
|
||||
@@ -65,7 +61,6 @@ export function PerfStats(props: {
|
||||
return columns;
|
||||
}, [props.events]);
|
||||
|
||||
const newLocal = [...frameworkEventsValue.entries()];
|
||||
return (
|
||||
<Layout.Container grow>
|
||||
<DataTable<PerformanceStatsEvent>
|
||||
@@ -79,11 +74,7 @@ export function PerfStats(props: {
|
||||
rootId: props.rootId,
|
||||
nodesCount: props.nodes.size,
|
||||
rootNode: props.nodes.get(props.rootId ?? 'noroot'),
|
||||
frameworkEvents: newLocal,
|
||||
frameworkEventsSize: newLocal.reduce(
|
||||
(acc, value) => acc + value[1].length,
|
||||
0,
|
||||
),
|
||||
frameworkEventsSize: props.frameworkEvents.size,
|
||||
}}></DataInspector>
|
||||
</DetailSidebar>
|
||||
</Layout.Container>
|
||||
|
||||
@@ -24,6 +24,7 @@ import React, {
|
||||
useRef,
|
||||
} from 'react';
|
||||
import {
|
||||
DataSource,
|
||||
getFlipperLib,
|
||||
HighlightManager,
|
||||
HighlightProvider,
|
||||
@@ -69,6 +70,7 @@ export type TreeNode = UINode & {
|
||||
idx: number;
|
||||
isExpanded: boolean;
|
||||
indentGuide: NodeIndentGuide | null;
|
||||
frameworkEvents: number | null;
|
||||
};
|
||||
export function Tree2({nodes, rootId}: {nodes: Map<Id, UINode>; rootId: Id}) {
|
||||
const instance = usePlugin(plugin);
|
||||
@@ -79,7 +81,6 @@ export function Tree2({nodes, rootId}: {nodes: Map<Id, UINode>; rootId: Id}) {
|
||||
const isContextMenuOpen = useValue(instance.uiState.isContextMenuOpen);
|
||||
const hoveredNode = head(useValue(instance.uiState.hoveredNodes));
|
||||
|
||||
const frameworkEvents = useValue(instance.frameworkEvents);
|
||||
const filterMainThreadMonitoring = useValue(
|
||||
instance.uiState.filterMainThreadMonitoring,
|
||||
);
|
||||
@@ -94,6 +95,9 @@ export function Tree2({nodes, rootId}: {nodes: Map<Id, UINode>; rootId: Id}) {
|
||||
focusedNode || rootId,
|
||||
expandedNodes,
|
||||
selectedNode?.id,
|
||||
instance.frameworkEvents,
|
||||
frameworkEventsMonitoring,
|
||||
filterMainThreadMonitoring,
|
||||
);
|
||||
|
||||
const refs: React.RefObject<HTMLLIElement>[] = treeNodes.map(() =>
|
||||
@@ -101,7 +105,16 @@ export function Tree2({nodes, rootId}: {nodes: Map<Id, UINode>; rootId: Id}) {
|
||||
);
|
||||
|
||||
return {treeNodes, refs};
|
||||
}, [expandedNodes, focusedNode, nodes, rootId, selectedNode]);
|
||||
}, [
|
||||
expandedNodes,
|
||||
filterMainThreadMonitoring,
|
||||
focusedNode,
|
||||
frameworkEventsMonitoring,
|
||||
instance.frameworkEvents,
|
||||
nodes,
|
||||
rootId,
|
||||
selectedNode?.id,
|
||||
]);
|
||||
|
||||
const isUsingKBToScrollUtill = useRef<MillisSinceEpoch>(0);
|
||||
|
||||
@@ -240,9 +253,6 @@ export function Tree2({nodes, rootId}: {nodes: Map<Id, UINode>; rootId: Id}) {
|
||||
innerRef={refs[virtualRow.index]}
|
||||
key={virtualRow.index}
|
||||
treeNode={treeNodes[virtualRow.index]}
|
||||
frameworkEvents={frameworkEvents}
|
||||
frameworkEventsMonitoring={frameworkEventsMonitoring}
|
||||
filterMainThreadMonitoring={filterMainThreadMonitoring}
|
||||
highlightedNodes={highlightedNodes}
|
||||
selectedNode={selectedNode?.id}
|
||||
hoveredNode={hoveredNode}
|
||||
@@ -292,9 +302,6 @@ function TreeItemContainer({
|
||||
transform,
|
||||
innerRef,
|
||||
treeNode,
|
||||
frameworkEvents,
|
||||
frameworkEventsMonitoring,
|
||||
filterMainThreadMonitoring,
|
||||
highlightedNodes,
|
||||
selectedNode,
|
||||
hoveredNode,
|
||||
@@ -308,10 +315,7 @@ function TreeItemContainer({
|
||||
transform: string;
|
||||
innerRef: Ref<any>;
|
||||
treeNode: TreeNode;
|
||||
frameworkEvents: Map<Id, FrameworkEvent[]>;
|
||||
highlightedNodes: Set<Id>;
|
||||
frameworkEventsMonitoring: Map<FrameworkEventType, boolean>;
|
||||
filterMainThreadMonitoring: boolean;
|
||||
selectedNode?: Id;
|
||||
hoveredNode?: Id;
|
||||
isUsingKBToScroll: RefObject<MillisSinceEpoch>;
|
||||
@@ -321,15 +325,6 @@ function TreeItemContainer({
|
||||
onCollapseNode: (node: Id) => void;
|
||||
onHoverNode: (node: Id) => void;
|
||||
}) {
|
||||
let events = frameworkEvents.get(treeNode.id);
|
||||
if (events) {
|
||||
events = events
|
||||
.filter((e) => frameworkEventsMonitoring.get(e.type))
|
||||
.filter(
|
||||
(e) => filterMainThreadMonitoring === false || e.thread === 'main',
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={innerRef}
|
||||
@@ -375,9 +370,9 @@ function TreeItemContainer({
|
||||
{nodeIcon(treeNode)}
|
||||
|
||||
<TreeItemRowContent treeNode={treeNode} />
|
||||
{events && (
|
||||
{treeNode.frameworkEvents && (
|
||||
<Badge
|
||||
count={events.length}
|
||||
count={treeNode.frameworkEvents}
|
||||
style={{
|
||||
backgroundColor: theme.primaryColor,
|
||||
marginLeft: theme.space.small,
|
||||
@@ -616,6 +611,9 @@ function toTreeNodes(
|
||||
rootId: Id,
|
||||
expandedNodes: Set<Id>,
|
||||
selectedNode: Id | undefined,
|
||||
frameworkEvents: DataSource<FrameworkEvent>,
|
||||
frameworkEventsMonitoring: Map<FrameworkEventType, boolean>,
|
||||
filterMainThreadMonitoring: boolean,
|
||||
): TreeNode[] {
|
||||
const root = nodes.get(rootId);
|
||||
if (root == null) {
|
||||
@@ -643,11 +641,21 @@ function toTreeNodes(
|
||||
const isExpanded = expandedNodes.has(node.id);
|
||||
const isSelected = node.id === selectedNode;
|
||||
|
||||
let events = frameworkEvents.getAllRecordsByIndex({nodeId: node.id});
|
||||
if (events) {
|
||||
events = events
|
||||
.filter((e) => frameworkEventsMonitoring.get(e.type))
|
||||
.filter(
|
||||
(e) => filterMainThreadMonitoring === false || e.thread === 'main',
|
||||
);
|
||||
}
|
||||
|
||||
treeNodes.push({
|
||||
...node,
|
||||
idx: i,
|
||||
depth,
|
||||
isExpanded,
|
||||
frameworkEvents: events.length > 0 ? events.length : null,
|
||||
indentGuide: stackItem.isChildOfSelectedNode
|
||||
? {
|
||||
depth: stackItem.selectedNodeDepth,
|
||||
|
||||
@@ -42,7 +42,6 @@ export const Inspector: React.FC<Props> = ({
|
||||
}) => {
|
||||
const instance = usePlugin(plugin);
|
||||
const selectedNodeId = useValue(instance.uiState.selectedNode)?.id;
|
||||
const frameworkEvents = useValue(instance.frameworkEvents);
|
||||
|
||||
const selectedNode = selectedNodeId ? nodes.get(selectedNodeId) : undefined;
|
||||
if (!selectedNode) {
|
||||
@@ -50,8 +49,8 @@ export const Inspector: React.FC<Props> = ({
|
||||
}
|
||||
|
||||
const selectedFrameworkEvents = selectedNodeId
|
||||
? frameworkEvents?.get(selectedNodeId)
|
||||
: undefined;
|
||||
? instance.frameworkEvents.getAllRecordsByIndex({nodeId: selectedNodeId})
|
||||
: [];
|
||||
|
||||
return (
|
||||
<Layout.Container gap pad>
|
||||
@@ -108,7 +107,7 @@ export const Inspector: React.FC<Props> = ({
|
||||
/>
|
||||
</Tab>
|
||||
)}
|
||||
{selectedFrameworkEvents && (
|
||||
{selectedFrameworkEvents?.length > 0 && (
|
||||
<Tab
|
||||
key={'events'}
|
||||
tab={
|
||||
|
||||
@@ -15,7 +15,7 @@ import {StackTraceInspector} from './StackTraceInspector';
|
||||
|
||||
type Props = {
|
||||
node: UINode;
|
||||
events: FrameworkEvent[];
|
||||
events: readonly FrameworkEvent[];
|
||||
showExtra?: (element: ReactNode) => void;
|
||||
};
|
||||
export const FrameworkEventsInspector: React.FC<Props> = ({
|
||||
@@ -41,7 +41,7 @@ export const FrameworkEventsInspector: React.FC<Props> = ({
|
||||
};
|
||||
|
||||
const hasStacktrace = (event: FrameworkEvent) => {
|
||||
return event.attribution?.type === 'stacktrace';
|
||||
return event?.attribution?.type === 'stacktrace';
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -143,7 +143,7 @@ export function plugin(client: PluginClient<Events>) {
|
||||
clearCallBack: async () => {
|
||||
uiState.streamState.set({state: 'Ok'});
|
||||
nodesAtom.set(new Map());
|
||||
frameworkEvents.set(new Map());
|
||||
frameworkEvents.clear();
|
||||
snapshot.set(null);
|
||||
},
|
||||
});
|
||||
@@ -191,7 +191,10 @@ export function plugin(client: PluginClient<Events>) {
|
||||
});
|
||||
|
||||
const nodesAtom = createState<Map<Id, UINode>>(new Map());
|
||||
const frameworkEvents = createState<Map<Id, FrameworkEvent[]>>(new Map());
|
||||
const frameworkEvents = createDataSource<FrameworkEvent>([], {
|
||||
indices: [['nodeId']],
|
||||
limit: 10000,
|
||||
});
|
||||
|
||||
const highlightedNodes = createState(new Set<Id>());
|
||||
const snapshot = createState<SnapshotInfo | null>(null);
|
||||
@@ -279,18 +282,9 @@ export function plugin(client: PluginClient<Events>) {
|
||||
};
|
||||
|
||||
function applyFrameworkEvents(frameScan: FrameScanEvent) {
|
||||
frameworkEvents.update((draft) => {
|
||||
if (frameScan?.frameworkEvents) {
|
||||
frameScan.frameworkEvents.forEach((frameworkEvent) => {
|
||||
const frameworkEventsForNode = draft.get(frameworkEvent.nodeId);
|
||||
if (frameworkEventsForNode) {
|
||||
frameworkEventsForNode.push(frameworkEvent);
|
||||
} else {
|
||||
draft.set(frameworkEvent.nodeId, [frameworkEvent]);
|
||||
for (const frameworkEvent of frameScan.frameworkEvents ?? []) {
|
||||
frameworkEvents.append(frameworkEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (uiState.isPaused.get() === true) {
|
||||
return;
|
||||
|
||||
@@ -110,6 +110,7 @@ type UpstreamEvent = {type: 'upstreamEvent'; eventId: Id};
|
||||
type FrameworkEventAttribution = Stacktrace | Reason | UpstreamEvent;
|
||||
|
||||
export type FrameworkEvent = {
|
||||
id: number;
|
||||
nodeId: Id;
|
||||
type: FrameworkEventType;
|
||||
timestamp: number;
|
||||
|
||||
Reference in New Issue
Block a user