Skip to content

Commit ccd071d

Browse files
Zylphrexandrewshie-sentry
authored andcommitted
ref(profiling): Merge profile provider for both modes (#83338)
This merges the 2 providers for transaction and continuous type profiles into 1 so that we can pass either type of profile to it anywhere instead of having 2 different providers.
1 parent 6d5d542 commit ccd071d

File tree

15 files changed

+228
-222
lines changed

15 files changed

+228
-222
lines changed

Diff for: static/app/components/events/interfaces/performance/spanEvidence.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function SpanEvidenceSection({event, organization, projectSlug}: Props) {
8080
<ProfilesProvider
8181
orgSlug={organization.slug}
8282
projectSlug={projectSlug}
83-
profileId={profileId || ''}
83+
profileMeta={profileId || ''}
8484
>
8585
<ProfileContext.Consumer>
8686
{profiles => (

Diff for: static/app/components/profiling/flamegraph/continuousFlamegraph.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ import {
6666
import {formatTo} from 'sentry/utils/profiling/units/units';
6767
import {useDevicePixelRatio} from 'sentry/utils/useDevicePixelRatio';
6868
import {useMemoWithPrevious} from 'sentry/utils/useMemoWithPrevious';
69-
import {
70-
useContinuousProfile,
71-
useContinuousProfileSegment,
72-
} from 'sentry/views/profiling/continuousProfileProvider';
7369
import {useProfileGroup} from 'sentry/views/profiling/profileGroupProvider';
70+
import {
71+
useProfiles,
72+
useProfileTransaction,
73+
} from 'sentry/views/profiling/profilesProvider';
7474

7575
import {FlamegraphDrawer} from './flamegraphDrawer/flamegraphDrawer';
7676
import {FlamegraphWarnings} from './flamegraphOverlays/FlamegraphWarnings';
@@ -246,9 +246,9 @@ export function ContinuousFlamegraph(): ReactElement {
246246
const devicePixelRatio = useDevicePixelRatio();
247247
const dispatch = useDispatchFlamegraphState();
248248

249-
const profiles = useContinuousProfile();
249+
const profiles = useProfiles();
250250
const profileGroup = useProfileGroup();
251-
const segment = useContinuousProfileSegment();
251+
const segment = useProfileTransaction();
252252

253253
const configSpaceQueryParam = useMemo(() => decodeConfigSpace(), []);
254254

Diff for: static/app/components/profiling/flamegraph/flamegraph.spec.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
66
import ProjectsStore from 'sentry/stores/projectsStore';
77
import {useParams} from 'sentry/utils/useParams';
88
import ProfileFlamegraph from 'sentry/views/profiling/profileFlamechart';
9-
import ProfilesAndTransactionProvider from 'sentry/views/profiling/profilesProvider';
9+
import ProfilesAndTransactionProvider from 'sentry/views/profiling/transactionProfileProvider';
1010

1111
jest.mock('sentry/utils/useParams', () => ({
1212
useParams: jest.fn(),

Diff for: static/app/components/profiling/flamegraph/flamegraph.tsx

+1-8
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ import {useProfileGroup} from 'sentry/views/profiling/profileGroupProvider';
6868
import {
6969
useProfiles,
7070
useProfileTransaction,
71-
useSetProfiles,
7271
} from 'sentry/views/profiling/profilesProvider';
7372

7473
import {FlamegraphDrawer} from './flamegraphDrawer/flamegraphDrawer';
@@ -219,7 +218,6 @@ function Flamegraph(): ReactElement {
219218
const dispatch = useDispatchFlamegraphState();
220219

221220
const profiles = useProfiles();
222-
const setProfiles = useSetProfiles();
223221
const profileGroup = useProfileGroup();
224222

225223
const flamegraphTheme = useFlamegraphTheme();
@@ -1314,12 +1312,7 @@ function Flamegraph(): ReactElement {
13141312
[dispatch]
13151313
);
13161314

1317-
const onImport = useCallback(
1318-
(p: Profiling.ProfileInput) => {
1319-
setProfiles({type: 'resolved', data: p});
1320-
},
1321-
[setProfiles]
1322-
);
1315+
const onImport = useCallback(() => {}, []);
13231316

13241317
useEffect(() => {
13251318
if (defined(flamegraphProfiles.threadId)) {

Diff for: static/app/routes.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -2184,7 +2184,9 @@ function buildRoutes() {
21842184
</Route>
21852185
<Route
21862186
path="profile/:projectId/:eventId/"
2187-
component={make(() => import('sentry/views/profiling/profilesProvider'))}
2187+
component={make(
2188+
() => import('sentry/views/profiling/transactionProfileProvider')
2189+
)}
21882190
>
21892191
<Route
21902192
path="flamegraph/"

Diff for: static/app/views/discover/eventDetails/content.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ function EventDetailsContent(props: Props) {
219219
<ProfilesProvider
220220
orgSlug={organization.slug}
221221
projectSlug={projectId}
222-
profileId={profileId || ''}
222+
profileMeta={profileId || ''}
223223
>
224224
<ProfileContext.Consumer>
225225
{profiles => (

Diff for: static/app/views/performance/newTraceDetails/traceDrawer/details/missingInstrumentation.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function MissingInstrumentationNodeDetails(
7373
<ProfilesProvider
7474
orgSlug={organization.slug}
7575
projectSlug={event?.projectSlug ?? ''}
76-
profileId={profileId || ''}
76+
profileMeta={profileId || ''}
7777
>
7878
<ProfileContext.Consumer>
7979
{profiles => (
@@ -191,7 +191,7 @@ function LegacyMissingInstrumentationNodeDetails({
191191
<ProfilesProvider
192192
orgSlug={organization.slug}
193193
projectSlug={node.event?.projectSlug ?? ''}
194-
profileId={profileId || ''}
194+
profileMeta={profileId || ''}
195195
>
196196
<ProfileContext.Consumer>
197197
{profiles => (

Diff for: static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ export function SpanNodeDetails({
253253
<ProfilesProvider
254254
orgSlug={organization.slug}
255255
projectSlug={node.event?.projectSlug}
256-
profileId={profileId || ''}
256+
profileMeta={profileId || ''}
257257
>
258258
<ProfileContext.Consumer>
259259
{profiles => (

Diff for: static/app/views/performance/traceDetails/newTraceDetailsTransactionBar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ function NewTraceDetailsTransactionBar(props: Props) {
483483
<ProfilesProvider
484484
orgSlug={organization.slug}
485485
projectSlug={embeddedChildren.projectSlug ?? ''}
486-
profileId={profileId || ''}
486+
profileMeta={profileId || ''}
487487
>
488488
<ProfileContext.Consumer>
489489
{profiles => (

Diff for: static/app/views/performance/traceDetails/traceViewDetailPanel.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ function SpanDetailsBody({
488488
<ProfilesProvider
489489
orgSlug={organization.slug}
490490
projectSlug={detail.event.projectSlug}
491-
profileId={profileId || ''}
491+
profileMeta={profileId || ''}
492492
>
493493
<ProfileContext.Consumer>
494494
{profiles => (

Diff for: static/app/views/performance/transactionDetails/content.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ function EventDetailsContent(props: Props) {
229229
<ProfilesProvider
230230
orgSlug={organization.slug}
231231
projectSlug={projectId}
232-
profileId={profileId || ''}
232+
profileMeta={profileId || ''}
233233
>
234234
<ProfileContext.Consumer>
235235
{profiles => (

Diff for: static/app/views/profiling/continuousProfileFlamegraph.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ import useOrganization from 'sentry/utils/useOrganization';
2525
import {useParams} from 'sentry/utils/useParams';
2626
import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider';
2727

28-
import {useContinuousProfile} from './continuousProfileProvider';
28+
import {useProfiles} from './profilesProvider';
2929

3030
function ContinuousProfileFlamegraph(): React.ReactElement {
3131
const organization = useOrganization();
32-
const profiles = useContinuousProfile();
32+
const profiles = useProfiles();
3333
const params = useParams();
3434

3535
const [storedPreferences] = useLocalStorageState<DeepPartial<FlamegraphState>>(
+15-122
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,15 @@
1-
import {createContext, useContext, useLayoutEffect, useMemo, useState} from 'react';
2-
import * as Sentry from '@sentry/react';
1+
import {useMemo, useState} from 'react';
32

4-
import type {Client} from 'sentry/api';
53
import {ContinuousProfileHeader} from 'sentry/components/profiling/continuousProfileHeader';
64
import type {RequestState} from 'sentry/types/core';
75
import type {EventTransaction} from 'sentry/types/event';
8-
import type {Organization} from 'sentry/types/organization';
9-
import type {Project} from 'sentry/types/project';
106
import {useSentryEvent} from 'sentry/utils/profiling/hooks/useSentryEvent';
117
import {decodeScalar} from 'sentry/utils/queryString';
12-
import useApi from 'sentry/utils/useApi';
138
import {useLocation} from 'sentry/utils/useLocation';
149
import useOrganization from 'sentry/utils/useOrganization';
1510
import {useParams} from 'sentry/utils/useParams';
16-
import useProjects from 'sentry/utils/useProjects';
1711

18-
interface ContinuousProfileQueryParams {
19-
end: string;
20-
profiler_id: string;
21-
start: string;
22-
}
23-
24-
function fetchContinuousProfileFlamegraph(
25-
api: Client,
26-
query: ContinuousProfileQueryParams,
27-
projectSlug: Project['slug'],
28-
orgSlug: Organization['slug']
29-
): Promise<Profiling.ProfileInput> {
30-
return api
31-
.requestPromise(`/organizations/${orgSlug}/profiling/chunks/`, {
32-
method: 'GET',
33-
query: {
34-
...query,
35-
project: projectSlug,
36-
},
37-
includeAllArgs: true,
38-
})
39-
.then(([data]) => data.chunk);
40-
}
41-
42-
type ContinuousProfileProviderValue = RequestState<Profiling.ProfileInput>;
43-
export const ContinuousProfileContext =
44-
createContext<ContinuousProfileProviderValue | null>(null);
45-
46-
export function useContinuousProfile() {
47-
const context = useContext(ContinuousProfileContext);
48-
if (!context) {
49-
throw new Error('useContinuousProfile was called outside of ProfileProvider');
50-
}
51-
return context;
52-
}
53-
54-
type ContinuousProfileSegmentProviderValue = RequestState<EventTransaction>;
55-
export const ContinuousProfileSegmentContext =
56-
createContext<ContinuousProfileSegmentProviderValue | null>(null);
57-
58-
export function useContinuousProfileSegment() {
59-
const context = useContext(ContinuousProfileSegmentContext);
60-
if (!context) {
61-
throw new Error(
62-
'useContinuousProfileSegment was called outside of ContinuousProfileSegmentProvider'
63-
);
64-
}
65-
return context;
66-
}
12+
import {ContinuousProfileProvider, ProfileTransactionContext} from './profilesProvider';
6713

6814
function isValidDate(date: string): boolean {
6915
return !isNaN(Date.parse(date));
@@ -73,7 +19,9 @@ interface FlamegraphViewProps {
7319
children: React.ReactNode;
7420
}
7521

76-
function ProfilesAndTransactionProvider(props: FlamegraphViewProps): React.ReactElement {
22+
export default function ProfileAndTransactionProvider(
23+
props: FlamegraphViewProps
24+
): React.ReactElement {
7725
const organization = useOrganization();
7826
const params = useParams();
7927
const location = useLocation();
@@ -100,88 +48,33 @@ function ProfilesAndTransactionProvider(props: FlamegraphViewProps): React.React
10048
};
10149
}, [location.query.start, location.query.end, location.query.profilerId]);
10250

51+
const [profile, setProfile] = useState<RequestState<Profiling.ProfileInput>>({
52+
type: 'initial',
53+
});
54+
10355
const profileTransaction = useSentryEvent<EventTransaction>(
10456
organization.slug,
10557
projectSlug!,
10658
decodeScalar(location.query.eventId) || null
10759
);
10860

10961
return (
110-
<ProfilesProvider
62+
<ContinuousProfileProvider
11163
orgSlug={organization.slug}
11264
profileMeta={profileMeta}
11365
projectSlug={projectSlug}
66+
profile={profile}
67+
setProfile={setProfile}
11468
>
115-
<ContinuousProfileSegmentContext.Provider value={profileTransaction}>
69+
<ProfileTransactionContext.Provider value={profileTransaction}>
11670
<ContinuousProfileHeader
11771
projectId={projectSlug}
11872
transaction={
11973
profileTransaction.type === 'resolved' ? profileTransaction.data : null
12074
}
12175
/>
12276
{props.children}
123-
</ContinuousProfileSegmentContext.Provider>
124-
</ProfilesProvider>
77+
</ProfileTransactionContext.Provider>
78+
</ContinuousProfileProvider>
12579
);
12680
}
127-
128-
interface ProfilesProviderProps {
129-
children: React.ReactNode;
130-
orgSlug: Organization['slug'];
131-
profileMeta: ContinuousProfileQueryParams | null;
132-
projectSlug: Project['slug'];
133-
onUpdateProfiles?: (profiles: RequestState<Profiling.ProfileInput>) => void;
134-
}
135-
136-
export function ProfilesProvider({
137-
children,
138-
onUpdateProfiles,
139-
orgSlug,
140-
profileMeta,
141-
projectSlug,
142-
}: ProfilesProviderProps) {
143-
const api = useApi();
144-
const {projects} = useProjects();
145-
146-
const [profiles, setProfiles] = useState<RequestState<Profiling.ProfileInput>>({
147-
type: 'initial',
148-
});
149-
150-
useLayoutEffect(() => {
151-
if (!profileMeta) {
152-
Sentry.captureMessage(
153-
'Failed to fetch continuous profile - invalid chunk parameters.'
154-
);
155-
return undefined;
156-
}
157-
158-
const project = projects.find(p => p.slug === projectSlug);
159-
if (!project) {
160-
Sentry.captureMessage('Failed to fetch continuous profile - project not found.');
161-
return undefined;
162-
}
163-
164-
setProfiles({type: 'loading'});
165-
166-
fetchContinuousProfileFlamegraph(api, profileMeta, project.id, orgSlug)
167-
.then(p => {
168-
setProfiles({type: 'resolved', data: p});
169-
onUpdateProfiles?.({type: 'resolved', data: p});
170-
})
171-
.catch(err => {
172-
setProfiles({type: 'errored', error: 'Failed to fetch profiles'});
173-
onUpdateProfiles?.({type: 'errored', error: 'Failed to fetch profiles'});
174-
Sentry.captureException(err);
175-
});
176-
177-
return () => api.clear();
178-
}, [api, onUpdateProfiles, profileMeta, orgSlug, projectSlug, projects]);
179-
180-
return (
181-
<ContinuousProfileContext.Provider value={profiles}>
182-
{children}
183-
</ContinuousProfileContext.Provider>
184-
);
185-
}
186-
187-
export default ProfilesAndTransactionProvider;

0 commit comments

Comments
 (0)