@@ -8,6 +8,7 @@ require('reflect-metadata');
8
8
import { GitpodClient , GitpodServer , GitpodServiceImpl , WorkspaceInstanceUpdateListener } from '@gitpod/gitpod-protocol/lib/gitpod-service' ;
9
9
import { JsonRpcProxyFactory } from '@gitpod/gitpod-protocol/lib/messaging/proxy-factory' ;
10
10
import { NavigatorContext , PullRequestContext , User } from '@gitpod/gitpod-protocol/lib/protocol' ;
11
+ import { ErrorCodes } from '@gitpod/gitpod-protocol/lib/messaging/error' ;
11
12
import { GitpodHostUrl } from '@gitpod/gitpod-protocol/lib/util/gitpod-host-url' ;
12
13
import { ControlServiceClient } from '@gitpod/supervisor-api-grpc/lib/control_grpc_pb' ;
13
14
import { InfoServiceClient } from '@gitpod/supervisor-api-grpc/lib/info_grpc_pb' ;
@@ -29,7 +30,7 @@ import ReconnectingWebSocket from 'reconnecting-websocket';
29
30
import { URL } from 'url' ;
30
31
import * as util from 'util' ;
31
32
import * 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' ;
33
34
import WebSocket = require( 'ws' ) ;
34
35
35
36
export class SupervisorConnection {
@@ -65,7 +66,7 @@ export class SupervisorConnection {
65
66
}
66
67
}
67
68
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' ] ;
69
70
type Union < Tuple extends any [ ] , Union = never > = Tuple [ number ] | Union ;
70
71
export type GitpodConnection = Omit < GitpodServiceImpl < GitpodClient , GitpodServer > , 'server' > & {
71
72
server : Pick < GitpodServer , Union < UsedGitpodFunction > >
@@ -203,7 +204,7 @@ export async function createGitpodExtensionContext(context: vscode.ExtensionCont
203
204
const gitpodApi = workspaceInfo . getGitpodApi ( ) ! ;
204
205
205
206
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' ] ;
207
208
const gitpodService : GitpodConnection = new GitpodServiceImpl < GitpodClient , GitpodServer > ( factory . createProxy ( ) ) as any ;
208
209
const gitpodScopes = new Set < string > ( [
209
210
'resource:workspace::' + workspaceId + '::get/update' ,
@@ -365,12 +366,28 @@ export async function registerWorkspaceCommands(context: GitpodExtensionContext)
365
366
) ) ;
366
367
context . subscriptions . push ( vscode . commands . registerCommand ( 'gitpod.takeSnapshot' , async ( ) => {
367
368
try {
368
- const snapshotId = await vscode . window . withProgress ( {
369
+ let snapshotId = '' ;
370
+ await vscode . window . withProgress ( {
369
371
location : vscode . ProgressLocation . Notification ,
370
372
cancellable : true ,
371
373
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
+ }
374
391
} ) ;
375
392
const hostname = context . info . getGitpodApi ( ) ! . getHost ( ) ;
376
393
const uri = `https://${ hostname } #snapshot/${ snapshotId } ` ;
0 commit comments