@@ -113,7 +113,6 @@ import { isDarkTheme, isLightTheme } from '../../../system/-webview/vscode';
113113import { openUrl } from '../../../system/-webview/vscode/uris' ;
114114import type { OpenWorkspaceLocation } from '../../../system/-webview/vscode/workspaces' ;
115115import { openWorkspace } from '../../../system/-webview/vscode/workspaces' ;
116- import { gate } from '../../../system/decorators/-webview/gate' ;
117116import { debug , log } from '../../../system/decorators/log' ;
118117import { disposableInterval } from '../../../system/function' ;
119118import type { Deferrable } from '../../../system/function/debounce' ;
@@ -247,7 +246,7 @@ const compactGraphColumnsSettings: GraphColumnsSettings = {
247246 sha : { width : 130 , isHidden : false , order : 6 } ,
248247} ;
249248
250- type CancellableOperations = 'hover' | 'computeIncludedRefs' | 'search' | 'state' ;
249+ type CancellableOperations = 'branchState' | ' hover' | 'computeIncludedRefs' | 'search' | 'state' ;
251250
252251export class GraphWebviewProvider implements WebviewProvider < State , State , GraphWebviewShowingArgs > {
253252 private _repository ?: Repository ;
@@ -1473,7 +1472,6 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
14731472 this . updateRefsMetadata ( ) ;
14741473 }
14751474
1476- @gate ( )
14771475 @debug ( )
14781476 private async onGetMoreRows ( e : GetMoreRowsParams , sendSelectedRows : boolean = false ) {
14791477 if ( this . _graph ?. paging == null ) return ;
@@ -1483,13 +1481,7 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
14831481 return ;
14841482 }
14851483
1486- using sw = new Stopwatch ( `GraohWebviewProvider.onGetMoreRows(${ this . host . id } )` ) ;
14871484 await this . updateGraphWithMoreRows ( this . _graph , e . id , this . _search ) ;
1488- this . container . telemetry . sendEvent ( 'graph/rows/loaded' , {
1489- ...this . getTelemetryContext ( ) ,
1490- duration : sw . elapsed ( ) ,
1491- rows : this . _graph . rows . length ?? 0 ,
1492- } ) ;
14931485 void this . notifyDidChangeRows ( sendSelectedRows ) ;
14941486 }
14951487
@@ -2201,14 +2193,18 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
22012193 const cancellation = this . createCancellation ( 'computeIncludedRefs' ) ;
22022194
22032195 const [ baseResult , defaultResult , targetResult ] = await Promise . allSettled ( [
2204- this . container . git . branches ( current . repoPath ) . getBaseBranchName ?.( current . name ) ,
2205- getDefaultBranchName ( this . container , current . repoPath , current . getRemoteName ( ) ) ,
2196+ this . container . git . branches ( current . repoPath ) . getBaseBranchName ?.( current . name , cancellation . token ) ,
2197+ getDefaultBranchName ( this . container , current . repoPath , current . getRemoteName ( ) , {
2198+ cancellation : cancellation . token ,
2199+ } ) ,
22062200 getTargetBranchName ( this . container , current , {
22072201 cancellation : cancellation . token ,
22082202 timeout : options ?. timeout ,
22092203 } ) ,
22102204 ] ) ;
22112205
2206+ if ( cancellation . token . isCancellationRequested ) return { refs : { } } ;
2207+
22122208 const baseBranchName = getSettledValue ( baseResult ) ;
22132209 const defaultBranchName = getSettledValue ( defaultResult ) ;
22142210 const targetMaybeResult = getSettledValue ( targetResult ) ;
@@ -2467,13 +2463,13 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
24672463 return item ;
24682464 }
24692465
2470- private async getWorkingTreeStats ( ) : Promise < GraphWorkingTreeStats | undefined > {
2466+ private async getWorkingTreeStats ( cancellation ?: CancellationToken ) : Promise < GraphWorkingTreeStats | undefined > {
24712467 if ( this . repository == null || this . container . git . repositoryCount === 0 ) return undefined ;
24722468
2473- const statusProivder = this . container . git . status ( this . repository . path ) ;
2474- const status = await statusProivder . getStatus ( ) ;
2469+ const statusProvider = this . container . git . status ( this . repository . path ) ;
2470+ const status = await statusProvider . getStatus ( cancellation ) ;
24752471 const workingTreeStatus = status ?. getDiffStatus ( ) ;
2476- const pausedOpStatus = await statusProivder . getPausedOperationStatus ?.( ) ;
2472+ const pausedOpStatus = await statusProvider . getPausedOperationStatus ?.( cancellation ) ;
24772473
24782474 return {
24792475 added : workingTreeStatus ?. added ?? 0 ,
@@ -2492,6 +2488,9 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
24922488 }
24932489
24942490 private async getState ( deferRows ?: boolean ) : Promise < State > {
2491+ this . cancelOperation ( 'branchState' ) ;
2492+ this . cancelOperation ( 'state' ) ;
2493+
24952494 if ( this . container . git . repositoryCount === 0 ) {
24962495 return { ...this . host . baseWebviewState , allowed : true , repositories : [ ] } ;
24972496 }
@@ -2503,6 +2502,8 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25032502 }
25042503 }
25052504
2505+ const cancellation = this . createCancellation ( 'state' ) ;
2506+
25062507 this . _etagRepository = this . repository ?. etag ;
25072508 this . host . title = `${ this . host . originalTitle } : ${ this . repository . formattedName } ` ;
25082509
@@ -2517,35 +2518,42 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25172518 const columns = this . getColumns ( ) ;
25182519 const columnSettings = this . getColumnSettings ( columns ) ;
25192520
2520- const dataPromise = this . repository . git . graph ( ) . getGraph ( rev , uri => this . host . asWebviewUri ( uri ) , {
2521- include : {
2522- stats :
2523- ( configuration . get ( 'graph.minimap.enabled' ) &&
2524- configuration . get ( 'graph.minimap.dataType' ) === 'lines' ) ||
2525- ! columnSettings . changes . isHidden ,
2521+ const dataPromise = this . repository . git . graph ( ) . getGraph (
2522+ rev ,
2523+ uri => this . host . asWebviewUri ( uri ) ,
2524+ {
2525+ include : {
2526+ stats :
2527+ ( configuration . get ( 'graph.minimap.enabled' ) &&
2528+ configuration . get ( 'graph.minimap.dataType' ) === 'lines' ) ||
2529+ ! columnSettings . changes . isHidden ,
2530+ } ,
2531+ limit : limit ,
25262532 } ,
2527- limit : limit ,
2528- } ) ;
2533+ cancellation . token ,
2534+ ) ;
25292535
25302536 // Check for access and working tree stats
25312537 const promises = Promise . allSettled ( [
25322538 this . getGraphAccess ( ) ,
2533- this . getWorkingTreeStats ( ) ,
2534- this . repository . git . branches ( ) . getBranch ( ) ,
2539+ this . getWorkingTreeStats ( cancellation . token ) ,
2540+ this . repository . git . branches ( ) . getBranch ( undefined , cancellation . token ) ,
25352541 this . repository . getLastFetched ( ) ,
25362542 ] ) ;
25372543
25382544 let data ;
25392545 if ( deferRows ) {
25402546 queueMicrotask ( async ( ) => {
2541- const data = await dataPromise ;
2542- this . setGraph ( data ) ;
2543- if ( selectedId !== uncommitted ) {
2544- this . setSelectedRows ( data . id ) ;
2545- }
2547+ try {
2548+ const data = await dataPromise ;
2549+ this . setGraph ( data ) ;
2550+ if ( selectedId !== uncommitted ) {
2551+ this . setSelectedRows ( data . id ) ;
2552+ }
25462553
2547- void this . notifyDidChangeRefsVisibility ( ) ;
2548- void this . notifyDidChangeRows ( true ) ;
2554+ void this . notifyDidChangeRefsVisibility ( ) ;
2555+ void this . notifyDidChangeRows ( true ) ;
2556+ } catch { }
25492557 } ) ;
25502558 } else {
25512559 data = await dataPromise ;
@@ -2556,6 +2564,8 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25562564 }
25572565
25582566 const [ accessResult , workingStatsResult , branchResult , lastFetchedResult ] = await promises ;
2567+ if ( cancellation . token . isCancellationRequested ) throw new CancellationError ( ) ;
2568+
25592569 const [ access , visibility ] = getSettledValue ( accessResult ) ?? [ ] ;
25602570
25612571 let branchState : BranchState | undefined ;
@@ -2564,17 +2574,18 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25642574 if ( branch != null ) {
25652575 branchState = { ...( branch . upstream ?. state ?? { ahead : 0 , behind : 0 } ) } ;
25662576
2567- const worktreesByBranch = data ?. worktreesByBranch ?? ( await getWorktreesByBranch ( this . repository ) ) ;
2577+ const worktreesByBranch =
2578+ data ?. worktreesByBranch ?? ( await getWorktreesByBranch ( this . repository , undefined , cancellation . token ) ) ;
25682579 branchState . worktree = worktreesByBranch ?. has ( branch . id ) ?? false ;
25692580
25702581 if ( branch . upstream != null ) {
25712582 branchState . upstream = branch . upstream . name ;
25722583
2573- const cancellation = this . createCancellation ( 'state ' ) ;
2584+ const branchStateCancellation = this . createCancellation ( 'branchState ' ) ;
25742585
25752586 const [ remoteResult , prResult ] = await Promise . allSettled ( [
25762587 branch . getRemote ( ) ,
2577- pauseOnCancelOrTimeout ( branch . getAssociatedPullRequest ( ) , cancellation . token , 100 ) ,
2588+ pauseOnCancelOrTimeout ( branch . getAssociatedPullRequest ( ) , branchStateCancellation . token , 100 ) ,
25782589 ] ) ;
25792590
25802591 const remote = getSettledValue ( remoteResult ) ;
@@ -2590,7 +2601,7 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
25902601 if ( maybePr ?. paused ) {
25912602 const updatedBranchState = { ...branchState } ;
25922603 void maybePr . value . then ( pr => {
2593- if ( cancellation ?. token . isCancellationRequested ) return ;
2604+ if ( branchStateCancellation ?. token . isCancellationRequested ) return ;
25942605
25952606 if ( pr != null ) {
25962607 updatedBranchState . pr = serializePullRequest ( pr ) ;
@@ -3044,9 +3055,68 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
30443055 }
30453056 }
30463057
3058+ private _pendingRowsQuery :
3059+ | {
3060+ promise : Promise < void > ;
3061+ cancellable : CancellationTokenSource ;
3062+ id ?: string | undefined ;
3063+ search ?: GitGraphSearch ;
3064+ }
3065+ | undefined ;
30473066 private async updateGraphWithMoreRows ( graph : GitGraph , id : string | undefined , search ?: GitGraphSearch ) {
3067+ if ( this . _pendingRowsQuery != null ) {
3068+ const { id : pendingId , search : pendingSearch } = this . _pendingRowsQuery ;
3069+ if ( pendingSearch === search && ( pendingId === id || ( pendingId != null && id == null ) ) ) {
3070+ return this . _pendingRowsQuery . promise ;
3071+ }
3072+
3073+ this . _pendingRowsQuery . cancellable . cancel ( ) ;
3074+ this . _pendingRowsQuery . cancellable . dispose ( ) ;
3075+ this . _pendingRowsQuery = undefined ;
3076+ }
3077+
3078+ const sw = new Stopwatch ( undefined ) ;
3079+
3080+ const cancellable = new CancellationTokenSource ( ) ;
3081+ const cancellation = cancellable . token ;
3082+
3083+ this . _pendingRowsQuery = {
3084+ promise : this . updateGraphWithMoreRowsCore ( graph , id , search , cancellation ) . catch ( ( ex : unknown ) => {
3085+ if ( cancellation . isCancellationRequested ) return ;
3086+
3087+ throw ex ;
3088+ } ) ,
3089+ cancellable : cancellable ,
3090+ id : id ,
3091+ search : search ,
3092+ } ;
3093+
3094+ void this . _pendingRowsQuery . promise . finally ( ( ) => {
3095+ if ( cancellation . isCancellationRequested ) return ;
3096+
3097+ this . container . telemetry . sendEvent ( 'graph/rows/loaded' , {
3098+ ...this . getTelemetryContext ( ) ,
3099+ duration : sw . elapsed ( ) ,
3100+ rows : graph . rows . length ?? 0 ,
3101+ } ) ;
3102+ sw . stop ( ) ;
3103+
3104+ this . _pendingRowsQuery = undefined ;
3105+ } ) ;
3106+
3107+ return this . _pendingRowsQuery . promise ;
3108+ }
3109+
3110+ private async updateGraphWithMoreRowsCore (
3111+ graph : GitGraph ,
3112+ id : string | undefined ,
3113+ search ?: GitGraphSearch ,
3114+ cancellation ?: CancellationToken ,
3115+ ) {
3116+ console . warn ( '##### updateGraphWithMoreRows' , id , search ) ;
3117+
30483118 const { defaultItemLimit, pageItemLimit } = configuration . get ( 'graph' ) ;
3049- const updatedGraph = await graph . more ?.( pageItemLimit ?? defaultItemLimit , id ) ;
3119+ const updatedGraph = await graph . more ?.( pageItemLimit ?? defaultItemLimit , id ?? undefined , cancellation ) ;
30503120 if ( updatedGraph != null ) {
30513121 this . setGraph ( updatedGraph ) ;
30523122
0 commit comments