|
@@ -1,4 +1,4 @@
|
|
|
-import {Fragment, ReactElement, useCallback, useMemo, useState} from 'react';
|
|
|
+import {Fragment, ReactElement, useMemo} from 'react';
|
|
|
import styled from '@emotion/styled';
|
|
|
|
|
|
import {FlamegraphOptionsMenu} from 'sentry/components/profiling/flamegraphOptionsMenu';
|
|
@@ -7,12 +7,16 @@ import {FlamegraphToolbar} from 'sentry/components/profiling/flamegraphToolbar';
|
|
|
import {FlamegraphViewSelectMenu} from 'sentry/components/profiling/flamegraphViewSelectMenu';
|
|
|
import {FlamegraphZoomView} from 'sentry/components/profiling/flamegraphZoomView';
|
|
|
import {FlamegraphZoomViewMinimap} from 'sentry/components/profiling/flamegraphZoomViewMinimap';
|
|
|
-import {ProfileDragDropImport} from 'sentry/components/profiling/profileDragDropImport';
|
|
|
+import {
|
|
|
+ ProfileDragDropImport,
|
|
|
+ ProfileDragDropImportProps,
|
|
|
+} from 'sentry/components/profiling/profileDragDropImport';
|
|
|
import {ThreadMenuSelector} from 'sentry/components/profiling/threadSelector';
|
|
|
import {CanvasPoolManager} from 'sentry/utils/profiling/canvasScheduler';
|
|
|
import {Flamegraph as FlamegraphModel} from 'sentry/utils/profiling/flamegraph';
|
|
|
import {FlamegraphTheme} from 'sentry/utils/profiling/flamegraph/flamegraphTheme';
|
|
|
import {useFlamegraphPreferences} from 'sentry/utils/profiling/flamegraph/useFlamegraphPreferences';
|
|
|
+import {useFlamegraphProfiles} from 'sentry/utils/profiling/flamegraph/useFlamegraphProfiles';
|
|
|
import {useFlamegraphTheme} from 'sentry/utils/profiling/flamegraph/useFlamegraphTheme';
|
|
|
import {Rect} from 'sentry/utils/profiling/gl/utils';
|
|
|
import {ProfileGroup} from 'sentry/utils/profiling/profile/importProfile';
|
|
@@ -24,44 +28,39 @@ function getTransactionConfigSpace(profiles: Profile[]): Rect {
|
|
|
return new Rect(startedAt, 0, endedAt - startedAt, 0);
|
|
|
}
|
|
|
interface FlamegraphProps {
|
|
|
+ onImport: ProfileDragDropImportProps['onImport'];
|
|
|
profiles: ProfileGroup;
|
|
|
}
|
|
|
|
|
|
function Flamegraph(props: FlamegraphProps): ReactElement {
|
|
|
const flamegraphTheme = useFlamegraphTheme();
|
|
|
const [{sorting, view, xAxis}, dispatch] = useFlamegraphPreferences();
|
|
|
- const canvasPoolManager = useMemo(() => new CanvasPoolManager(), []);
|
|
|
-
|
|
|
- const [activeProfileIndex, setActiveProfileIndex] = useState<number | null>(null);
|
|
|
- const [importedProfiles, setImportedProfiles] = useState<ProfileGroup | null>(null);
|
|
|
+ const [{activeProfileIndex}, dispatchActiveProfileIndex] = useFlamegraphProfiles();
|
|
|
|
|
|
- // once an import occurs, it will always take precedence over the profile in the props
|
|
|
- const profiles = importedProfiles ?? props.profiles;
|
|
|
+ const canvasPoolManager = useMemo(() => new CanvasPoolManager(), []);
|
|
|
|
|
|
const flamegraph = useMemo(() => {
|
|
|
+ if (
|
|
|
+ !props.profiles.profiles[activeProfileIndex ?? props.profiles.activeProfileIndex]
|
|
|
+ ) {
|
|
|
+ // This could happen if activeProfileIndex was initialized from query string, but for some
|
|
|
+ // reason the profile was removed from the list of profiles.
|
|
|
+ return FlamegraphModel.Empty();
|
|
|
+ }
|
|
|
// if the activeProfileIndex is null, use the activeProfileIndex from the profile group
|
|
|
- const profileIndex = activeProfileIndex ?? profiles.activeProfileIndex;
|
|
|
-
|
|
|
- const flamegraphModel = new FlamegraphModel(
|
|
|
- profiles.profiles[profileIndex],
|
|
|
- profileIndex,
|
|
|
+ return new FlamegraphModel(
|
|
|
+ props.profiles.profiles[activeProfileIndex ?? props.profiles.activeProfileIndex],
|
|
|
+ activeProfileIndex ?? props.profiles.activeProfileIndex,
|
|
|
{
|
|
|
inverted: view === 'bottom up',
|
|
|
leftHeavy: sorting === 'left heavy',
|
|
|
configSpace:
|
|
|
xAxis === 'transaction'
|
|
|
- ? getTransactionConfigSpace(profiles.profiles)
|
|
|
+ ? getTransactionConfigSpace(props.profiles.profiles)
|
|
|
: undefined,
|
|
|
}
|
|
|
);
|
|
|
-
|
|
|
- return flamegraphModel;
|
|
|
- }, [profiles, activeProfileIndex, sorting, xAxis, view]);
|
|
|
-
|
|
|
- const onImport = useCallback((profile: ProfileGroup) => {
|
|
|
- setActiveProfileIndex(null);
|
|
|
- setImportedProfiles(profile);
|
|
|
- }, []);
|
|
|
+ }, [props.profiles, activeProfileIndex, sorting, xAxis, view]);
|
|
|
|
|
|
return (
|
|
|
<Fragment>
|
|
@@ -69,7 +68,9 @@ function Flamegraph(props: FlamegraphProps): ReactElement {
|
|
|
<ThreadMenuSelector
|
|
|
profileGroup={props.profiles}
|
|
|
activeProfileIndex={flamegraph.profileIndex}
|
|
|
- onProfileIndexChange={setActiveProfileIndex}
|
|
|
+ onProfileIndexChange={index =>
|
|
|
+ dispatchActiveProfileIndex({type: 'set active profile index', payload: index})
|
|
|
+ }
|
|
|
/>
|
|
|
<FlamegraphViewSelectMenu
|
|
|
view={view}
|
|
@@ -95,9 +96,8 @@ function Flamegraph(props: FlamegraphProps): ReactElement {
|
|
|
/>
|
|
|
</FlamegraphZoomViewMinimapContainer>
|
|
|
<FlamegraphZoomViewContainer>
|
|
|
- <ProfileDragDropImport onImport={onImport}>
|
|
|
+ <ProfileDragDropImport onImport={props.onImport}>
|
|
|
<FlamegraphZoomView
|
|
|
- key={`${profiles.traceID}-${flamegraph.profileIndex}`}
|
|
|
flamegraph={flamegraph}
|
|
|
canvasPoolManager={canvasPoolManager}
|
|
|
/>
|