@@ -8,6 +8,7 @@ require('reflect-metadata');
88import  {  GitpodClient ,  GitpodServer ,  GitpodServiceImpl ,  WorkspaceInstanceUpdateListener  }  from  '@gitpod/gitpod-protocol/lib/gitpod-service' ; 
99import  {  JsonRpcProxyFactory  }  from  '@gitpod/gitpod-protocol/lib/messaging/proxy-factory' ; 
1010import  {  NavigatorContext ,  PullRequestContext ,  User  }  from  '@gitpod/gitpod-protocol/lib/protocol' ; 
11+ import  {  ErrorCodes  }  from  '@gitpod/gitpod-protocol/lib/messaging/error' ; 
1112import  {  GitpodHostUrl  }  from  '@gitpod/gitpod-protocol/lib/util/gitpod-host-url' ; 
1213import  {  ControlServiceClient  }  from  '@gitpod/supervisor-api-grpc/lib/control_grpc_pb' ; 
1314import  {  InfoServiceClient  }  from  '@gitpod/supervisor-api-grpc/lib/info_grpc_pb' ; 
@@ -29,7 +30,7 @@ import ReconnectingWebSocket from 'reconnecting-websocket';
2930import  {  URL  }  from  'url' ; 
3031import  *  as  util  from  'util' ; 
3132import  *  as  vscode  from  'vscode' ; 
32- import  {  ConsoleLogger ,  listen  as  doListen  }  from  'vscode-ws-jsonrpc' ; 
33+ import  {  CancellationToken ,   ConsoleLogger ,  listen  as  doListen  }  from  'vscode-ws-jsonrpc' ; 
3334import  WebSocket  =  require( 'ws' ) ; 
3435
3536export  class  SupervisorConnection  { 
@@ -65,7 +66,7 @@ export class SupervisorConnection {
6566	} 
6667} 
6768
68- type  UsedGitpodFunction  =  [ 'getWorkspace' ,  'openPort' ,  'stopWorkspace' ,  'setWorkspaceTimeout' ,  'getWorkspaceTimeout' ,  'getLoggedInUser' ,  'takeSnapshot' ,  'controlAdmission' ,  'sendHeartBeat' ,  'trackEvent' ] ; 
69+ type  UsedGitpodFunction  =  [ 'getWorkspace' ,  'openPort' ,  'stopWorkspace' ,  'setWorkspaceTimeout' ,  'getWorkspaceTimeout' ,  'getLoggedInUser' ,  'takeSnapshot' ,  'waitForSnapshot'  ,   ' controlAdmission',  'sendHeartBeat' ,  'trackEvent' ] ; 
6970type  Union < Tuple  extends  any [ ] ,  Union  =  never >  =  Tuple [ number ]  |  Union ; 
7071export  type  GitpodConnection  =  Omit < GitpodServiceImpl < GitpodClient ,  GitpodServer > ,  'server' >  &  { 
7172	server : Pick < GitpodServer ,  Union < UsedGitpodFunction > > 
@@ -203,7 +204,7 @@ export async function createGitpodExtensionContext(context: vscode.ExtensionCont
203204	const  gitpodApi  =  workspaceInfo . getGitpodApi ( ) ! ; 
204205
205206	const  factory  =  new  JsonRpcProxyFactory < GitpodServer > ( ) ; 
206- 	const  gitpodFunctions : UsedGitpodFunction  =  [ 'getWorkspace' ,  'openPort' ,  'stopWorkspace' ,  'setWorkspaceTimeout' ,  'getWorkspaceTimeout' ,  'getLoggedInUser' ,  'takeSnapshot' ,  'controlAdmission' ,  'sendHeartBeat' ,  'trackEvent' ] ; 
207+ 	const  gitpodFunctions : UsedGitpodFunction  =  [ 'getWorkspace' ,  'openPort' ,  'stopWorkspace' ,  'setWorkspaceTimeout' ,  'getWorkspaceTimeout' ,  'getLoggedInUser' ,  'takeSnapshot' ,  'waitForSnapshot'  ,   ' controlAdmission',  'sendHeartBeat' ,  'trackEvent' ] ; 
207208	const  gitpodService : GitpodConnection  =  new  GitpodServiceImpl < GitpodClient ,  GitpodServer > ( factory . createProxy ( ) )  as  any ; 
208209	const  gitpodScopes  =  new  Set < string > ( [ 
209210		'resource:workspace::'  +  workspaceId  +  '::get/update' , 
@@ -365,12 +366,28 @@ export async function registerWorkspaceCommands(context: GitpodExtensionContext)
365366	) ) ; 
366367	context . subscriptions . push ( vscode . commands . registerCommand ( 'gitpod.takeSnapshot' ,  async  ( )  =>  { 
367368		try  { 
368- 			const  snapshotId  =  await  vscode . window . withProgress ( { 
369+ 			let  snapshotId  =  '' ; 
370+ 			await  vscode . window . withProgress ( { 
369371				location : vscode . ProgressLocation . Notification , 
370372				cancellable : true , 
371373				title : 'Capturing workspace snapshot' 
372- 			} ,  _  =>  { 
373- 				return  context . gitpod . server . takeSnapshot ( {  workspaceId : context . info . getWorkspaceId ( )  /*, layoutData?*/  } ) ; 
374+ 			} ,  async  ( _ ,  cancelToken : CancellationToken )  =>  { 
375+ 				snapshotId  =  await  context . gitpod . server . takeSnapshot ( {  workspaceId : context . info . getWorkspaceId ( )  /*, layoutData?*/  } ) ; 
376+ 
377+ 				while  ( ! cancelToken . isCancellationRequested )  { 
378+ 					try  { 
379+ 						await  context . gitpod . server . waitForSnapshot ( snapshotId ) ; 
380+ 						return ; 
381+ 					}  catch  ( err )  { 
382+ 						if  ( err . code  ===  ErrorCodes . SNAPSHOT_ERROR  ||  err . code  ===  ErrorCodes . NOT_FOUND )  { 
383+ 							// this is indeed an error with snapshot creation itself, break here! 
384+ 							throw  err ; 
385+ 						} 
386+ 
387+ 						// other errors (like connection errors): retry 
388+ 						await  new  Promise ( ( resolve )  =>  setTimeout ( resolve ,  3000 ) ) ; 
389+ 					} 
390+ 				} 
374391			} ) ; 
375392			const  hostname  =  context . info . getGitpodApi ( ) ! . getHost ( ) ; 
376393			const  uri  =  `https://${ hostname } ${ snapshotId }  ; 
0 commit comments