-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add TraceContext class for tracking asynchronous dependencies for pag…
…e load. (#21492) ## Summary & Motivation Similar in spirit to #21414. It provides a mechanism for Cloud to use to track outstanding asynchronous dependencies for the current page. In particular we need to know: - When a dependency is created/added - When a dependency is completed - When a dependency is cancelled (eg. it didn't complete but we're aborting it because we're navigating away) It's important to distinguish between completed and "cancelled" loads for understanding the metrics. ## How I Tested These Changes jest tests
- Loading branch information
Showing
5 changed files
with
203 additions
and
210 deletions.
There are no files selected for viewing
100 changes: 0 additions & 100 deletions
100
js_modules/dagster-ui/packages/ui-core/src/app/TrackedSuspense.tsx
This file was deleted.
Oops, something went wrong.
110 changes: 0 additions & 110 deletions
110
js_modules/dagster-ui/packages/ui-core/src/app/__tests__/TrackedSuspense.test.tsx
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
js_modules/dagster-ui/packages/ui-core/src/performance/TraceContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import {QueryResult} from '@apollo/client'; | ||
import {ReactNode, createContext, useContext, useLayoutEffect, useMemo} from 'react'; | ||
|
||
export enum CompletionType { | ||
SUCCESS = 1, | ||
ERROR = 2, | ||
CANCELLED = 3, | ||
} | ||
|
||
type TraceContextType = { | ||
createDependency: (_name: string) => Dependency | null; | ||
addDependency: (_dep: Dependency | null) => void; | ||
completeDependency: (_dep: Dependency | null, type: CompletionType) => void; | ||
}; | ||
|
||
export const TraceContext = createContext<TraceContextType>({ | ||
createDependency: (_name: string) => null, | ||
addDependency: (_dep) => {}, | ||
completeDependency: (_dep, _type) => {}, | ||
}); | ||
|
||
/** | ||
* Use this to wrap child react components who should not count | ||
* toward display done. Eg. If you're re-using a component that | ||
* adds dependencies but you don't want that component or its dependencies | ||
* as your own dependency | ||
*/ | ||
export const OrphanDependenciesTraceContext = ({children}: {children: ReactNode}) => { | ||
return ( | ||
<TraceContext.Provider | ||
value={useMemo( | ||
() => ({ | ||
createDependency: () => null, | ||
addDependency: () => {}, | ||
completeDependency: () => {}, | ||
}), | ||
[], | ||
)} | ||
> | ||
{children} | ||
</TraceContext.Provider> | ||
); | ||
}; | ||
|
||
export class Dependency { | ||
public readonly name: string; | ||
|
||
constructor(name: string) { | ||
this.name = name; | ||
} | ||
} | ||
|
||
/** Use this to declare a dependency on an apollo query result */ | ||
export function useBlockTraceOnQueryResult(queryResult: QueryResult<any>, name: string) { | ||
const dep = useDependency(name); | ||
const hasData = !!queryResult.data; | ||
const hasError = !!queryResult.error; | ||
|
||
useLayoutEffect(() => { | ||
if (hasData) { | ||
dep.completeDependency(CompletionType.SUCCESS); | ||
} | ||
}, [dep, hasData]); | ||
|
||
useLayoutEffect(() => { | ||
if (!hasData && hasError) { | ||
dep.completeDependency(CompletionType.ERROR); | ||
} | ||
}, [dep, hasData, hasError]); | ||
} | ||
|
||
export function useDependency(name: string) { | ||
const {addDependency, completeDependency, createDependency} = useContext(TraceContext); | ||
|
||
const dependency = useMemo(() => createDependency(name), [createDependency, name]); | ||
|
||
useLayoutEffect(() => { | ||
addDependency(dependency); | ||
return () => { | ||
// By default cancel a dependency when the component unmounts. | ||
// Rely on the user of TraceContext to track if the dependency | ||
// was already completed prior to this. | ||
completeDependency(dependency, CompletionType.CANCELLED); | ||
}; | ||
}, [addDependency, completeDependency, dependency]); | ||
|
||
return useMemo( | ||
() => ({ | ||
completeDependency: (type: CompletionType) => { | ||
completeDependency(dependency, type); | ||
}, | ||
}), | ||
[completeDependency, dependency], | ||
); | ||
} |
Oops, something went wrong.
0c02efa
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.
Deploy preview for dagit-core-storybook ready!
✅ Preview
https://dagit-core-storybook-57hss4vsh-elementl.vercel.app
Built with commit 0c02efa.
This pull request is being automatically deployed with vercel-action