@@ -5,8 +5,8 @@ import { Emitter } from "@coder/events";
5
5
import { logger , field } from "@coder/logger" ;
6
6
import { ReadWriteConnection , InitData , SharedProcessData } from "../common/connection" ;
7
7
import { Module , ServerProxy } from "../common/proxy" ;
8
- import { stringify , parse , moduleToProto , protoToModule , protoToOperatingSystem } from "../common/util" ;
9
- import { Ping , ServerMessage , ClientMessage , MethodMessage , NamedProxyMessage , NumberedProxyMessage , SuccessMessage , FailMessage , EventMessage , CallbackMessage } from "../proto" ;
8
+ import { argumentToProto , protoToArgument , moduleToProto , protoToModule , protoToOperatingSystem } from "../common/util" ;
9
+ import { Argument , Ping , ServerMessage , ClientMessage , Method , Event , Callback } from "../proto" ;
10
10
import { FsModule , ChildProcessModule , NetModule , NodePtyModule , SpdlogModule , TrashModule } from "./modules" ;
11
11
12
12
// tslint:disable no-any
@@ -24,8 +24,8 @@ export class Client {
24
24
private messageId = 0 ;
25
25
private callbackId = 0 ;
26
26
private readonly proxies = new Map < number | Module , ProxyData > ( ) ;
27
- private readonly successEmitter = new Emitter < SuccessMessage > ( ) ;
28
- private readonly failEmitter = new Emitter < FailMessage > ( ) ;
27
+ private readonly successEmitter = new Emitter < Method . Success > ( ) ;
28
+ private readonly failEmitter = new Emitter < Method . Fail > ( ) ;
29
29
private readonly eventEmitter = new Emitter < { event : string ; args : any [ ] ; } > ( ) ;
30
30
31
31
private _initData : InitData | undefined ;
@@ -129,9 +129,9 @@ export class Client {
129
129
field ( "event listeners" , this . eventEmitter . counts ) ,
130
130
] ) ;
131
131
132
- const message = new FailMessage ( ) ;
132
+ const message = new Method . Fail ( ) ;
133
133
const error = new Error ( "disconnected" ) ;
134
- message . setResponse ( stringify ( error ) ) ;
134
+ message . setResponse ( argumentToProto ( error ) ) ;
135
135
this . failEmitter . emit ( message ) ;
136
136
137
137
this . eventEmitter . emit ( { event : "disconnected" , args : [ error ] } ) ;
@@ -182,20 +182,21 @@ export class Client {
182
182
case "kill" :
183
183
return Promise . resolve ( ) ;
184
184
}
185
+
185
186
return Promise . reject (
186
187
new Error ( `Unable to call "${ method } " on proxy ${ proxyId } : disconnected` ) ,
187
188
) ;
188
189
}
189
190
190
- const message = new MethodMessage ( ) ;
191
+ const message = new Method ( ) ;
191
192
const id = this . messageId ++ ;
192
- let proxyMessage : NamedProxyMessage | NumberedProxyMessage ;
193
+ let proxyMessage : Method . Named | Method . Numbered ;
193
194
if ( typeof proxyId === "string" ) {
194
- proxyMessage = new NamedProxyMessage ( ) ;
195
+ proxyMessage = new Method . Named ( ) ;
195
196
proxyMessage . setModule ( moduleToProto ( proxyId ) ) ;
196
197
message . setNamedProxy ( proxyMessage ) ;
197
198
} else {
198
- proxyMessage = new NumberedProxyMessage ( ) ;
199
+ proxyMessage = new Method . Numbered ( ) ;
199
200
proxyMessage . setProxyId ( proxyId ) ;
200
201
message . setNumberedProxy ( proxyMessage ) ;
201
202
}
@@ -215,16 +216,16 @@ export class Client {
215
216
return callbackId ;
216
217
} ;
217
218
218
- const stringifiedArgs = args . map ( ( a ) => stringify ( a , storeCallback ) ) ;
219
+ const protoArgs = args . map ( ( a ) => argumentToProto ( a , storeCallback ) ) ;
219
220
logger . trace ( ( ) => [
220
221
"sending" ,
221
222
field ( "id" , id ) ,
222
223
field ( "proxyId" , proxyId ) ,
223
224
field ( "method" , method ) ,
224
- field ( "args" , stringifiedArgs ) ,
225
+ field ( "args" , protoArgs ) ,
225
226
] ) ;
226
227
227
- proxyMessage . setArgsList ( stringifiedArgs ) ;
228
+ proxyMessage . setArgsList ( protoArgs ) ;
228
229
229
230
const clientMessage = new ClientMessage ( ) ;
230
231
clientMessage . setMethod ( message ) ;
@@ -246,12 +247,12 @@ export class Client {
246
247
247
248
const d1 = this . successEmitter . event ( id , ( message ) => {
248
249
dispose ( ) ;
249
- resolve ( this . parse ( message . getResponse ( ) , promise ) ) ;
250
+ resolve ( this . protoToArgument ( message . getResponse ( ) , promise ) ) ;
250
251
} ) ;
251
252
252
253
const d2 = this . failEmitter . event ( id , ( message ) => {
253
254
dispose ( ) ;
254
- reject ( parse ( message . getResponse ( ) ) ) ;
255
+ reject ( protoToArgument ( message . getResponse ( ) ) ) ;
255
256
} ) ;
256
257
} ) ;
257
258
@@ -262,42 +263,53 @@ export class Client {
262
263
* Handle all messages from the server.
263
264
*/
264
265
private async handleMessage ( message : ServerMessage ) : Promise < void > {
265
- if ( message . hasInit ( ) ) {
266
- const init = message . getInit ( ) ! ;
267
- this . _initData = {
268
- dataDirectory : init . getDataDirectory ( ) ,
269
- homeDirectory : init . getHomeDirectory ( ) ,
270
- tmpDirectory : init . getTmpDirectory ( ) ,
271
- workingDirectory : init . getWorkingDirectory ( ) ,
272
- os : protoToOperatingSystem ( init . getOperatingSystem ( ) ) ,
273
- shell : init . getShell ( ) ,
274
- builtInExtensionsDirectory : init . getBuiltinExtensionsDir ( ) ,
275
- } ;
276
- this . initDataEmitter . emit ( this . _initData ) ;
277
- } else if ( message . hasSuccess ( ) ) {
278
- this . emitSuccess ( message . getSuccess ( ) ! ) ;
279
- } else if ( message . hasFail ( ) ) {
280
- this . emitFail ( message . getFail ( ) ! ) ;
281
- } else if ( message . hasEvent ( ) ) {
282
- await this . emitEvent ( message . getEvent ( ) ! ) ;
283
- } else if ( message . hasCallback ( ) ) {
284
- await this . runCallback ( message . getCallback ( ) ! ) ;
285
- } else if ( message . hasSharedProcessActive ( ) ) {
286
- const sharedProcessActiveMessage = message . getSharedProcessActive ( ) ! ;
287
- this . sharedProcessActiveEmitter . emit ( {
288
- socketPath : sharedProcessActiveMessage . getSocketPath ( ) ,
289
- logPath : sharedProcessActiveMessage . getLogPath ( ) ,
290
- } ) ;
291
- } else if ( message . hasPong ( ) ) {
292
- // Nothing to do since pings are on a timer rather than waiting for the
293
- // next pong in case a message from either the client or server is dropped
294
- // which would break the ping cycle.
295
- } else {
296
- throw new Error ( "unknown message type" ) ;
266
+ switch ( message . getMsgCase ( ) ) {
267
+ case ServerMessage . MsgCase . INIT :
268
+ const init = message . getInit ( ) ! ;
269
+ this . _initData = {
270
+ dataDirectory : init . getDataDirectory ( ) ,
271
+ homeDirectory : init . getHomeDirectory ( ) ,
272
+ tmpDirectory : init . getTmpDirectory ( ) ,
273
+ workingDirectory : init . getWorkingDirectory ( ) ,
274
+ os : protoToOperatingSystem ( init . getOperatingSystem ( ) ) ,
275
+ shell : init . getShell ( ) ,
276
+ builtInExtensionsDirectory : init . getBuiltinExtensionsDir ( ) ,
277
+ } ;
278
+ this . initDataEmitter . emit ( this . _initData ) ;
279
+ break ;
280
+ case ServerMessage . MsgCase . SUCCESS :
281
+ this . emitSuccess ( message . getSuccess ( ) ! ) ;
282
+ break ;
283
+ case ServerMessage . MsgCase . FAIL :
284
+ this . emitFail ( message . getFail ( ) ! ) ;
285
+ break ;
286
+ case ServerMessage . MsgCase . EVENT :
287
+ await this . emitEvent ( message . getEvent ( ) ! ) ;
288
+ break ;
289
+ case ServerMessage . MsgCase . CALLBACK :
290
+ await this . runCallback ( message . getCallback ( ) ! ) ;
291
+ break ;
292
+ case ServerMessage . MsgCase . SHARED_PROCESS_ACTIVE :
293
+ const sharedProcessActiveMessage = message . getSharedProcessActive ( ) ! ;
294
+ this . sharedProcessActiveEmitter . emit ( {
295
+ socketPath : sharedProcessActiveMessage . getSocketPath ( ) ,
296
+ logPath : sharedProcessActiveMessage . getLogPath ( ) ,
297
+ } ) ;
298
+ break ;
299
+ case ServerMessage . MsgCase . PONG :
300
+ // Nothing to do since pings are on a timer rather than waiting for the
301
+ // next pong in case a message from either the client or server is dropped
302
+ // which would break the ping cycle.
303
+ break ;
304
+ default :
305
+ throw new Error ( "unknown message type" ) ;
297
306
}
298
307
}
299
308
300
- private emitSuccess ( message : SuccessMessage ) : void {
309
+ /**
310
+ * Convert message to a success event.
311
+ */
312
+ private emitSuccess ( message : Method . Success ) : void {
301
313
logger . trace ( ( ) => [
302
314
"received resolve" ,
303
315
field ( "id" , message . getId ( ) ) ,
@@ -306,7 +318,10 @@ export class Client {
306
318
this . successEmitter . emit ( message . getId ( ) , message ) ;
307
319
}
308
320
309
- private emitFail ( message : FailMessage ) : void {
321
+ /**
322
+ * Convert message to a fail event.
323
+ */
324
+ private emitFail ( message : Method . Fail ) : void {
310
325
logger . trace ( ( ) => [
311
326
"received reject" ,
312
327
field ( "id" , message . getId ( ) ) ,
@@ -322,7 +337,7 @@ export class Client {
322
337
* request before it emits. Instead, emit all events from the server so all
323
338
* events are always caught on the client.
324
339
*/
325
- private async emitEvent ( message : EventMessage ) : Promise < void > {
340
+ private async emitEvent ( message : Event ) : Promise < void > {
326
341
const eventMessage = message . getNamedEvent ( ) ! || message . getNumberedEvent ( ) ! ;
327
342
const proxyId = message . getNamedEvent ( )
328
343
? protoToModule ( message . getNamedEvent ( ) ! . getModule ( ) )
@@ -336,7 +351,7 @@ export class Client {
336
351
field ( "args" , eventMessage . getArgsList ( ) ) ,
337
352
] ) ;
338
353
339
- const args = eventMessage . getArgsList ( ) . map ( ( a ) => this . parse ( a ) ) ;
354
+ const args = eventMessage . getArgsList ( ) . map ( ( a ) => this . protoToArgument ( a ) ) ;
340
355
this . eventEmitter . emit ( proxyId , { event, args } ) ;
341
356
}
342
357
@@ -348,7 +363,7 @@ export class Client {
348
363
* also only be used when passed together with the method. If they are sent
349
364
* afterward, they may never be called due to timing issues.
350
365
*/
351
- private async runCallback ( message : CallbackMessage ) : Promise < void > {
366
+ private async runCallback ( message : Callback ) : Promise < void > {
352
367
const callbackMessage = message . getNamedCallback ( ) ! || message . getNumberedCallback ( ) ! ;
353
368
const proxyId = message . getNamedCallback ( )
354
369
? protoToModule ( message . getNamedCallback ( ) ! . getModule ( ) )
@@ -361,14 +376,14 @@ export class Client {
361
376
field ( "callbackId" , callbackId ) ,
362
377
field ( "args" , callbackMessage . getArgsList ( ) ) ,
363
378
] ) ;
364
- const args = callbackMessage . getArgsList ( ) . map ( ( a ) => this . parse ( a ) ) ;
379
+ const args = callbackMessage . getArgsList ( ) . map ( ( a ) => this . protoToArgument ( a ) ) ;
365
380
this . getProxy ( proxyId ) . callbacks . get ( callbackId ) ! ( ...args ) ;
366
381
}
367
382
368
383
/**
369
384
* Start the ping loop. Does nothing if already pinging.
370
385
*/
371
- private startPinging = ( ) : void => {
386
+ private readonly startPinging = ( ) : void => {
372
387
if ( typeof this . pingTimeout !== "undefined" ) {
373
388
return ;
374
389
}
@@ -505,10 +520,16 @@ export class Client {
505
520
await this . getProxy ( proxyId ) . promise ;
506
521
}
507
522
508
- private parse ( value ?: string , promise ?: Promise < any > ) : any {
509
- return parse ( value , undefined , ( id ) => this . createProxy ( id , promise ) ) ;
523
+ /**
524
+ * Same as protoToArgument except provides createProxy.
525
+ */
526
+ private protoToArgument ( value ?: Argument , promise ?: Promise < any > ) : any {
527
+ return protoToArgument ( value , undefined , ( id ) => this . createProxy ( id , promise ) ) ;
510
528
}
511
529
530
+ /**
531
+ * Get a proxy. Error if it doesn't exist.
532
+ */
512
533
private getProxy ( proxyId : number | Module ) : ProxyData {
513
534
if ( ! this . proxies . has ( proxyId ) ) {
514
535
throw new Error ( `proxy ${ proxyId } disposed too early` ) ;
0 commit comments