@@ -4,84 +4,62 @@ import { getPathFromAmdModule } from "vs/base/common/amd";
4
4
import { VSBuffer } from "vs/base/common/buffer" ;
5
5
import { Emitter } from "vs/base/common/event" ;
6
6
import { ISocket } from "vs/base/parts/ipc/common/ipc.net" ;
7
- import { NodeSocket , WebSocketNodeSocket } from "vs/base/parts/ipc/node/ipc.net" ;
7
+ import { NodeSocket } from "vs/base/parts/ipc/node/ipc.net" ;
8
8
import { ILogService } from "vs/platform/log/common/log" ;
9
9
import { IExtHostReadyMessage , IExtHostSocketMessage } from "vs/workbench/services/extensions/common/extensionHostProtocol" ;
10
10
11
11
import { Protocol } from "vs/server/src/protocol" ;
12
12
import { uriTransformerPath } from "vs/server/src/util" ;
13
13
14
14
export abstract class Connection {
15
- private readonly _onClose = new Emitter < void > ( ) ;
15
+ protected readonly _onClose = new Emitter < void > ( ) ;
16
16
public readonly onClose = this . _onClose . event ;
17
+ protected disposed : boolean = false ;
17
18
18
- private timeout : NodeJS . Timeout | undefined ;
19
- private readonly wait = 1000 * 60 ;
20
-
21
- private closed : boolean = false ;
22
-
23
- public constructor ( protected protocol : Protocol ) {
24
- // onClose seems to mean we want to disconnect, so close immediately.
25
- protocol . onClose ( ( ) => this . close ( ) ) ;
26
-
27
- // If the socket closes, we want to wait before closing so we can
28
- // reconnect in the meantime.
29
- protocol . onSocketClose ( ( ) => {
30
- this . timeout = setTimeout ( ( ) => {
31
- this . close ( ) ;
32
- } , this . wait ) ;
33
- } ) ;
34
- }
19
+ public constructor ( protected protocol : Protocol ) { }
35
20
36
21
/**
37
22
* Set up the connection on a new socket.
38
23
*/
39
- public reconnect ( protocol : Protocol , buffer : VSBuffer ) : void {
40
- if ( this . closed ) {
41
- throw new Error ( "Cannot reconnect to closed connection" ) ;
42
- }
43
- clearTimeout ( this . timeout as any ) ; // Not sure why the type doesn't work.
44
- this . protocol = protocol ;
45
- this . connect ( protocol . getSocket ( ) , buffer ) ;
46
- }
47
-
48
- /**
49
- * Close and clean up connection. This will also kill the socket the
50
- * connection is on. Probably not safe to reconnect once this has happened.
51
- */
52
- protected close ( ) : void {
53
- if ( ! this . closed ) {
54
- this . closed = true ;
55
- this . protocol . sendDisconnect ( ) ;
56
- this . dispose ( ) ;
57
- this . protocol . dispose ( ) ;
58
- this . _onClose . fire ( ) ;
59
- }
60
- }
24
+ public abstract reconnect ( socket : ISocket , buffer : VSBuffer ) : void ;
61
25
62
26
/**
63
27
* Clean up the connection.
64
28
*/
65
29
protected abstract dispose ( ) : void ;
66
-
67
- /**
68
- * Connect to a new socket.
69
- */
70
- protected abstract connect ( socket : ISocket , buffer : VSBuffer ) : void ;
71
30
}
72
31
73
32
/**
74
33
* Used for all the IPC channels.
75
34
*/
76
35
export class ManagementConnection extends Connection {
77
- protected dispose ( ) : void {
78
- // Nothing extra to do here.
36
+ private timeout : NodeJS . Timeout | undefined ;
37
+ private readonly wait = 1000 * 60 ;
38
+
39
+ public constructor ( protocol : Protocol ) {
40
+ super ( protocol ) ;
41
+ protocol . onClose ( ( ) => this . dispose ( ) ) ;
42
+ protocol . onSocketClose ( ( ) => {
43
+ this . timeout = setTimeout ( ( ) => this . dispose ( ) , this . wait ) ;
44
+ } ) ;
79
45
}
80
46
81
- protected connect ( socket : ISocket , buffer : VSBuffer ) : void {
47
+ public reconnect ( socket : ISocket , buffer : VSBuffer ) : void {
48
+ clearTimeout ( this . timeout as any ) ; // Not sure why the type doesn't work.
82
49
this . protocol . beginAcceptReconnection ( socket , buffer ) ;
83
50
this . protocol . endAcceptReconnection ( ) ;
84
51
}
52
+
53
+ protected dispose ( ) : void {
54
+ if ( ! this . disposed ) {
55
+ clearTimeout ( this . timeout as any ) ; // Not sure why the type doesn't work.
56
+ this . disposed = true ;
57
+ this . protocol . sendDisconnect ( ) ;
58
+ this . protocol . dispose ( ) ;
59
+ this . protocol . getSocket ( ) . end ( ) ;
60
+ this . _onClose . fire ( ) ;
61
+ }
62
+ }
85
63
}
86
64
87
65
/**
@@ -90,38 +68,45 @@ export class ManagementConnection extends Connection {
90
68
export class ExtensionHostConnection extends Connection {
91
69
private process : cp . ChildProcess ;
92
70
93
- public constructor ( protocol : Protocol , private readonly log : ILogService ) {
71
+ public constructor (
72
+ protocol : Protocol , buffer : VSBuffer ,
73
+ private readonly log : ILogService ,
74
+ ) {
94
75
super ( protocol ) ;
95
- const socket = this . protocol . getSocket ( ) ;
96
- const buffer = this . protocol . readEntireBuffer ( ) ;
97
- this . process = this . spawn ( socket , buffer ) ;
76
+ protocol . dispose ( ) ;
77
+ this . process = this . spawn ( buffer ) ;
98
78
}
99
79
100
80
protected dispose ( ) : void {
101
- this . process . kill ( ) ;
81
+ if ( ! this . disposed ) {
82
+ this . disposed = true ;
83
+ this . process . kill ( ) ;
84
+ this . protocol . getSocket ( ) . end ( ) ;
85
+ this . _onClose . fire ( ) ;
86
+ }
102
87
}
103
88
104
- protected connect ( socket : ISocket , buffer : VSBuffer ) : void {
105
- this . sendInitMessage ( socket , buffer ) ;
89
+ public reconnect ( socket : ISocket , buffer : VSBuffer ) : void {
90
+ // This is just to set the new socket.
91
+ this . protocol . beginAcceptReconnection ( socket , null ) ;
92
+ this . protocol . dispose ( ) ;
93
+ this . sendInitMessage ( buffer ) ;
106
94
}
107
95
108
- private sendInitMessage ( nodeSocket : ISocket , buffer : VSBuffer ) : void {
109
- const socket = nodeSocket instanceof NodeSocket
110
- ? nodeSocket . socket
111
- : ( nodeSocket as WebSocketNodeSocket ) . socket . socket ;
112
-
96
+ private sendInitMessage ( buffer : VSBuffer ) : void {
97
+ const socket = this . protocol . getUnderlyingSocket ( ) ;
113
98
socket . pause ( ) ;
114
99
115
100
const initMessage : IExtHostSocketMessage = {
116
101
type : "VSCODE_EXTHOST_IPC_SOCKET" ,
117
102
initialDataChunk : ( buffer . buffer as Buffer ) . toString ( "base64" ) ,
118
- skipWebSocketFrames : nodeSocket instanceof NodeSocket ,
103
+ skipWebSocketFrames : this . protocol . getSocket ( ) instanceof NodeSocket ,
119
104
} ;
120
105
121
106
this . process . send ( initMessage , socket ) ;
122
107
}
123
108
124
- private spawn ( socket : ISocket , buffer : VSBuffer ) : cp . ChildProcess {
109
+ private spawn ( buffer : VSBuffer ) : cp . ChildProcess {
125
110
const proc = cp . fork (
126
111
getPathFromAmdModule ( require , "bootstrap-fork" ) ,
127
112
[
@@ -142,20 +127,15 @@ export class ExtensionHostConnection extends Connection {
142
127
} ,
143
128
) ;
144
129
145
- proc . on ( "error" , ( error ) => {
146
- console . error ( error ) ;
147
- this . close ( ) ;
148
- } ) ;
149
-
150
- proc . on ( "exit" , ( code , signal ) => {
151
- console . error ( "Extension host exited" , { code, signal } ) ;
152
- this . close ( ) ;
153
- } ) ;
130
+ proc . on ( "error" , ( ) => this . dispose ( ) ) ;
131
+ proc . on ( "exit" , ( ) => this . dispose ( ) ) ;
154
132
155
133
proc . stdout . setEncoding ( "utf8" ) ;
156
134
proc . stderr . setEncoding ( "utf8" ) ;
157
- proc . stdout . on ( "data" , ( data ) => this . log . info ( "Extension host stdout" , data ) ) ;
158
- proc . stderr . on ( "data" , ( data ) => this . log . error ( "Extension host stderr" , data ) ) ;
135
+
136
+ proc . stdout . on ( "data" , ( d ) => this . log . info ( "Extension host stdout" , d ) ) ;
137
+ proc . stderr . on ( "data" , ( d ) => this . log . error ( "Extension host stderr" , d ) ) ;
138
+
159
139
proc . on ( "message" , ( event ) => {
160
140
if ( event && event . type === "__$console" ) {
161
141
const severity = this . log [ event . severity ] ? event . severity : "info" ;
@@ -166,10 +146,9 @@ export class ExtensionHostConnection extends Connection {
166
146
const listen = ( message : IExtHostReadyMessage ) => {
167
147
if ( message . type === "VSCODE_EXTHOST_IPC_READY" ) {
168
148
proc . removeListener ( "message" , listen ) ;
169
- this . sendInitMessage ( socket , buffer ) ;
149
+ this . sendInitMessage ( buffer ) ;
170
150
}
171
151
} ;
172
-
173
152
proc . on ( "message" , listen ) ;
174
153
175
154
return proc ;
0 commit comments