6
6
import { GitpodClient , GitpodServer , GitpodServiceImpl } from '@gitpod/gitpod-protocol/lib/gitpod-service' ;
7
7
import { JsonRpcProxyFactory } from '@gitpod/gitpod-protocol/lib/messaging/proxy-factory' ;
8
8
import { listen as doListen } from 'vscode-ws-jsonrpc' ;
9
- import WebSocket from 'ws' ;
9
+ import WebSocket , { ErrorEvent } from 'ws' ;
10
10
import ReconnectingWebSocket from 'reconnecting-websocket' ;
11
11
import * as vscode from 'vscode' ;
12
12
import Log from './common/logger' ;
@@ -22,9 +22,9 @@ export const unauthorizedErr = 'unauthorized';
22
22
class GitpodServerApi extends vscode . Disposable {
23
23
24
24
readonly service : GitpodConnection ;
25
- private readonly webSocket : any ;
26
- private readonly onWillCloseEmitter = new vscode . EventEmitter < number | undefined > ( ) ;
27
- readonly onWillClose = this . onWillCloseEmitter . event ;
25
+ private readonly webSocket : ReconnectingWebSocket ;
26
+ private readonly onErrorEmitter = new vscode . EventEmitter < Error > ( ) ;
27
+ readonly onError = this . onErrorEmitter . event ;
28
28
29
29
constructor ( accessToken : string , serviceUrl : string , private readonly logger : Log ) {
30
30
super ( ( ) => this . internalDispose ( ) ) ;
@@ -34,14 +34,12 @@ class GitpodServerApi extends vscode.Disposable {
34
34
const factory = new JsonRpcProxyFactory < GitpodServer > ( ) ;
35
35
this . service = new GitpodServiceImpl < GitpodClient , GitpodServer > ( factory . createProxy ( ) ) ;
36
36
37
- let retry = 1 ;
38
- const maxRetries = 3 ;
39
37
const webSocket = new ReconnectingWebSocket ( `${ serviceUrl . replace ( 'https' , 'wss' ) } /api/v1` , undefined , {
40
38
maxReconnectionDelay : 10000 ,
41
39
minReconnectionDelay : 1000 ,
42
40
reconnectionDelayGrowFactor : 1.5 ,
43
41
connectionTimeout : 10000 ,
44
- maxRetries : Infinity ,
42
+ maxRetries : 3 ,
45
43
debug : false ,
46
44
startClosed : false ,
47
45
WebSocket : class extends WebSocket {
@@ -54,19 +52,10 @@ class GitpodServerApi extends vscode.Disposable {
54
52
'X-Client-Version' : vscode . version
55
53
}
56
54
} ) ;
57
- this . on ( 'unexpected-response' , ( _ , resp ) => {
58
- this . terminate ( ) ;
59
-
60
- // if mal-formed handshake request (unauthorized, forbidden) or client actions (redirect) are required then fail immediately
61
- // otherwise try several times and fail, maybe temporarily unavailable, like server restart
62
- if ( retry ++ >= maxRetries || ( typeof resp . statusCode === 'number' && 300 <= resp . statusCode && resp . statusCode < 500 ) ) {
63
- webSocket . close ( resp . statusCode ) ;
64
- }
65
- } ) ;
66
55
}
67
56
}
68
57
} ) ;
69
- webSocket . onerror = ( e : any ) => logger . error ( 'internal server api: failed to open socket' , e ) ;
58
+ webSocket . onerror = ( e : ErrorEvent ) => this . onErrorEmitter . fire ( e . error ) ;
70
59
71
60
doListen ( {
72
61
webSocket : ( webSocket as any ) ,
@@ -76,31 +65,18 @@ class GitpodServerApi extends vscode.Disposable {
76
65
this . webSocket = webSocket ;
77
66
}
78
67
79
- private close ( statusCode ?: number ) : void {
80
- this . onWillCloseEmitter . fire ( statusCode ) ;
81
- try {
82
- this . webSocket . close ( ) ;
83
- } catch ( e ) {
84
- this . logger . error ( 'internal server api: failed to close socket' , e ) ;
85
- }
86
- }
87
-
88
68
internalDispose ( ) {
89
- this . close ( ) ;
90
- this . onWillCloseEmitter . dispose ( ) ;
69
+ this . webSocket . close ( ) ;
70
+ this . onErrorEmitter . dispose ( ) ;
91
71
}
92
72
}
93
73
94
74
export function withServerApi < T > ( accessToken : string , serviceUrl : string , cb : ( service : GitpodConnection ) => Promise < T > , logger : Log ) : Promise < T > {
95
75
const api = new GitpodServerApi ( accessToken , serviceUrl , logger ) ;
96
76
return Promise . race ( [
97
77
cb ( api . service ) ,
98
- new Promise < T > ( ( _ , reject ) => api . onWillClose ( statusCode => {
99
- if ( statusCode === 401 ) {
100
- reject ( new Error ( unauthorizedErr ) ) ;
101
- } else {
102
- reject ( new Error ( 'closed' ) ) ;
103
- }
78
+ new Promise < T > ( ( _ , reject ) => api . onError ( error => {
79
+ reject ( error ) ;
104
80
} ) )
105
81
] ) . finally ( ( ) => api . dispose ( ) ) ;
106
82
}
0 commit comments