Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import {
ExecutionDigestsResponse,
ExecutionDataResponse,
GraphExecutionDataResponse,
SourceFileResponse,
} from '../data_source/tfdbg2_data_source';

Expand Down Expand Up @@ -144,6 +145,24 @@ export const numGraphExecutionsLoaded = createAction(
props<{numGraphExecutions: number}>()
);

export const graphExecutionDataRequested = createAction(
'[Debugger] Intra-Graph Execution Data Requested',
props<{pageIndex: number}>()
);

export const graphExecutionDataLoaded = createAction(
'[Debugger] Intra-Graph Execution Data Loaded',
props<GraphExecutionDataResponse>()
);

export const graphExecutionScrollToIndex = createAction(
'[Debugger] Scroll Intra-Graph Execution List to Given Index',
props<{index: number}>()
);

/**
* Actions related to source files and stack traces.
*/
export const sourceFileListRequested = createAction(
'[Debugger] Source File List Requested.'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ limitations under the License.

.bottom-section {
border-top: 1px solid rgba(0, 0, 0, 0.12);
height: 353px;
height: 34%;
padding-top: 6px;
width: 100%;
}

.debugger-container {
background-color: #fff;
height: 100%;
}

.top-section {
height: 360px;
height: 66%;
padding: 6px 0;
width: 100%;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
limitations under the License.
-->

<div>
<div class="debugger-container">
<tf-debugger-v2-inactive
*ngIf="runIds.length === 0; else dataAvailable"
></tf-debugger-v2-inactive>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {Store} from '@ngrx/store';
import {Actions, createEffect, ofType} from '@ngrx/effects';
import {merge, Observable} from 'rxjs';
import {
debounceTime,
filter,
map,
mergeMap,
Expand All @@ -37,6 +38,9 @@ import {
executionScrollLeft,
executionScrollRight,
executionScrollToIndex,
graphExecutionDataLoaded,
graphExecutionDataRequested,
graphExecutionScrollToIndex,
numAlertsAndBreakdownLoaded,
numAlertsAndBreakdownRequested,
numExecutionsLoaded,
Expand All @@ -61,6 +65,11 @@ import {
getExecutionPageSize,
getExecutionScrollBeginIndex,
getFocusedSourceFileContent,
getGraphExecutionDataPageLoadedSizes,
getGraphExecutionDisplayCount,
getGraphExecutionPageSize,
getGraphExecutionScrollBeginIndex,
getGraphExecutionDataLoadingPages,
getNumExecutions,
getNumExecutionsLoaded,
getLoadedAlertsOfFocusedType,
Expand Down Expand Up @@ -541,6 +550,109 @@ export class DebuggerEffects {
);
}

/**
* Emits when scrolling event leads to need to load new intra-graph execution
* data.
*
* The returned observable contains the
* - runId: active runId,
* - missingPage: indices of missing `GraphExecution` pages that need to be
* loaded by a downstream pipe.
* - pageSize: GraphExecution data page size.
* - numGraphExecutions: Current total number of `GraphExecution`s.
*/
private onGraphExecutionScroll(): Observable<{
runId: string;
missingPages: number[];
pageSize: number;
numGraphExecutions: number;
}> {
return this.actions$.pipe(
ofType(graphExecutionScrollToIndex),
debounceTime(100),
withLatestFrom(
this.store.select(getActiveRunId),
this.store.select(getNumGraphExecutions),
this.store.select(getGraphExecutionScrollBeginIndex)
),
filter(([, runId, numGraphExecutions]) => {
return runId !== null && numGraphExecutions > 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it a tiny bit readable, can we only select the things we need here? i.e., move L565-566 to L588?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}),
map(([, runId, numGraphExecutions, scrollBeginIndex]) => ({
runId,
numGraphExecutions,
scrollBeginIndex,
})),
withLatestFrom(
this.store.select(getGraphExecutionPageSize),
this.store.select(getGraphExecutionDisplayCount),
this.store.select(getGraphExecutionDataLoadingPages),
this.store.select(getGraphExecutionDataPageLoadedSizes)
),
map(
([
{runId, numGraphExecutions, scrollBeginIndex},
pageSize,
displayCount,
loadingPages,
pageLoadedSizes,
]) => {
let missingPages: number[] = getMissingPages(
scrollBeginIndex,
Math.min(scrollBeginIndex + displayCount, numGraphExecutions),
pageSize,
numGraphExecutions,
pageLoadedSizes
);
// Omit pages that are already loading.
missingPages = missingPages.filter(
(page) => loadingPages.indexOf(page) === -1
);
return {
runId: runId!,
missingPages,
pageSize,
numGraphExecutions,
};
}
)
);
}

private loadGraphExecutionPages(
prevStream$: Observable<{
runId: string;
missingPages: number[];
pageSize: number;
numGraphExecutions: number;
}>
): Observable<void> {
return prevStream$.pipe(
filter(({missingPages}) => missingPages.length > 0),
tap(({missingPages}) => {
missingPages.forEach((pageIndex) => {
this.store.dispatch(graphExecutionDataRequested({pageIndex}));
});
}),
mergeMap(({runId, missingPages, pageSize, numGraphExecutions}) => {
const begin = missingPages[0] * pageSize;
const end = Math.min(
(missingPages[missingPages.length - 1] + 1) * pageSize,
numGraphExecutions
);
return this.dataSource.fetchGraphExecutionData(runId!, begin, end).pipe(
tap((graphExecutionDataResponse) => {
this.store.dispatch(
graphExecutionDataLoaded(graphExecutionDataResponse)
);
}),
map(() => void null)
);
// TODO(cais): Add catchError() to pipe.
})
);
}

/**
* Emits when user focuses on an alert type.
*
Expand Down Expand Up @@ -766,6 +878,8 @@ export class DebuggerEffects {
*
* on source file requested ---> fetch source file
*
* on graph-execution scroll --> fetch graph-execution data
*
**/
this.loadData$ = createEffect(
() => {
Expand Down Expand Up @@ -827,14 +941,19 @@ export class DebuggerEffects {

const onSourceFileFocused$ = this.onSourceFileFocused();

const onGraphExecutionScroll$ = this.loadGraphExecutionPages(
this.onGraphExecutionScroll()
);

// ExecutionDigest and ExecutionData can be loaded in parallel.
return merge(
onNumAlertsLoaded$,
onExcutionDigestLoaded$,
onExecutionDataLoaded$,
onNumGraphExecutionLoaded$,
loadSourceFileList$,
onSourceFileFocused$
onSourceFileFocused$,
onGraphExecutionScroll$
).pipe(
// createEffect expects an Observable that emits {}.
map(() => ({}))
Expand Down
Loading