@@ -1225,10 +1225,10 @@ index 0000000000000000000000000000000000000000..4ea6d95d36aaac07dbd4d0e16ab3c1bb
12251225+ }
12261226diff --git a/src/vs/server/entry.ts b/src/vs/server/entry.ts
12271227new file mode 100644
1228- index 0000000000000000000000000000000000000000..ab020fbb4e4ab3748cc807765ff9c362389faafa
1228+ index 0000000000000000000000000000000000000000..8482c48bae007ed6b39183001ae2cc6d140fcd50
12291229--- /dev/null
12301230+++ b/src/vs/server/entry.ts
1231- @@ -0,0 +1,78 @@
1231+ @@ -0,0 +1,79 @@
12321232+ import { field } from '@coder/logger';
12331233+ import { setUnexpectedErrorHandler } from 'vs/base/common/errors';
12341234+ import { CodeServerMessage, VscodeMessage } from 'vs/server/ipc';
@@ -1273,7 +1273,8 @@ index 0000000000000000000000000000000000000000..ab020fbb4e4ab3748cc807765ff9c362
12731273+ // Wait for the init message then start up VS Code. Subsequent messages will
12741274+ // return new workbench options without starting a new instance.
12751275+ process.on('message', async (message: CodeServerMessage, socket) => {
1276- + logger.debug('got message from code-server', field('message', message));
1276+ + logger.debug('got message from code-server', field('type', message.type));
1277+ + logger.trace('code-server message content', field('message', message));
12771278+ switch (message.type) {
12781279+ case 'init':
12791280+ try {
@@ -1821,21 +1822,20 @@ index 0000000000000000000000000000000000000000..609c4d1cb43f52f92906b901c14c790f
18211822+ }
18221823diff --git a/src/vs/server/node/connection.ts b/src/vs/server/node/connection.ts
18231824new file mode 100644
1824- index 0000000000000000000000000000000000000000..eec198c948d48b1539ff46510016f759f396be18
1825+ index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81e6a0e039
18251826--- /dev/null
18261827+++ b/src/vs/server/node/connection.ts
1827- @@ -0,0 +1,157 @@
1828+ @@ -0,0 +1,171 @@
1829+ + import { field, Logger, logger } from '@coder/logger';
18281830+ import * as cp from 'child_process';
18291831+ import { VSBuffer } from 'vs/base/common/buffer';
18301832+ import { Emitter } from 'vs/base/common/event';
18311833+ import { FileAccess } from 'vs/base/common/network';
18321834+ import { ISocket } from 'vs/base/parts/ipc/common/ipc.net';
18331835+ import { NodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
18341836+ import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
1835- + import { ILogService } from 'vs/platform/log/common/log';
18361837+ import { getNlsConfiguration } from 'vs/server/node/nls';
18371838+ import { Protocol } from 'vs/server/node/protocol';
1838- + import { IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
18391839+
18401840+ export abstract class Connection {
18411841+ private readonly _onClose = new Emitter<void>();
@@ -1899,13 +1899,14 @@ index 0000000000000000000000000000000000000000..eec198c948d48b1539ff46510016f759
18991899+
19001900+ export class ExtensionHostConnection extends Connection {
19011901+ private process?: cp.ChildProcess;
1902+ + private readonly logger: Logger;
19021903+
19031904+ public constructor(
19041905+ locale:string, protocol: Protocol, buffer: VSBuffer, token: string,
1905- + private readonly log: ILogService,
19061906+ private readonly environment: INativeEnvironmentService,
19071907+ ) {
19081908+ super(protocol, token);
1909+ + this.logger = logger.named("exthost", field("token", token));
19091910+ this.protocol.dispose();
19101911+ this.spawn(locale, buffer).then((p) => this.process = p);
19111912+ this.protocol.getUnderlyingSocket().pause();
@@ -1928,6 +1929,7 @@ index 0000000000000000000000000000000000000000..eec198c948d48b1539ff46510016f759
19281929+ private sendInitMessage(buffer: VSBuffer): void {
19291930+ const socket = this.protocol.getUnderlyingSocket();
19301931+ socket.pause();
1932+ + this.logger.trace('Sending socket');
19311933+ this.process!.send({ // Process must be set at this point.
19321934+ type: 'VSCODE_EXTHOST_IPC_SOCKET',
19331935+ initialDataChunk: (buffer.buffer as Buffer).toString('base64'),
@@ -1936,7 +1938,9 @@ index 0000000000000000000000000000000000000000..eec198c948d48b1539ff46510016f759
19361938+ }
19371939+
19381940+ private async spawn(locale: string, buffer: VSBuffer): Promise<cp.ChildProcess> {
1941+ + this.logger.trace('Getting NLS configuration...');
19391942+ const config = await getNlsConfiguration(locale, this.environment.userDataPath);
1943+ + this.logger.trace('Spawning extension host...');
19401944+ const proc = cp.fork(
19411945+ FileAccess.asFileUri('bootstrap-fork', require).fsPath,
19421946+ [ '--type=extensionHost' ],
@@ -1956,30 +1960,41 @@ index 0000000000000000000000000000000000000000..eec198c948d48b1539ff46510016f759
19561960+ },
19571961+ );
19581962+
1959- + proc.on('error', () => this.dispose());
1960- + proc.on('exit', () => this.dispose());
1963+ + proc.on('error', (error) => {
1964+ + this.logger.error('Exited unexpectedly', field('error', error));
1965+ + this.dispose();
1966+ + });
1967+ + proc.on('exit', (code) => {
1968+ + this.logger.trace('Exited', field('code', code));
1969+ + this.dispose();
1970+ + });
19611971+ if (proc.stdout && proc.stderr) {
1962- + proc.stdout.setEncoding('utf8').on('data', (d) => this.log .info('Extension host stdout', d));
1963- + proc.stderr.setEncoding('utf8').on('data', (d) => this.log .error('Extension host stderr', d));
1972+ + proc.stdout.setEncoding('utf8').on('data', (d) => this.logger .info(d));
1973+ + proc.stderr.setEncoding('utf8').on('data', (d) => this.logger .error(d));
19641974+ }
1975+ +
19651976+ proc.on('message', (event) => {
1966- + if (event && event.type === '__$console') {
1967- + const severity = (<any>this.log)[event.severity] ? event.severity : 'info';
1968- + (<any>this.log)[severity]('Extension host', event.arguments);
1969- + }
1970- + if (event && event.type === 'VSCODE_EXTHOST_DISCONNECTED') {
1971- + this.setOffline();
1977+ + switch (event && event.type) {
1978+ + case '__$console':
1979+ + const severity = (<any>this.logger)[event.severity] || 'info';
1980+ + (<any>this.logger)[severity]('console', field('arguments', event.arguments));
1981+ + break;
1982+ + case 'VSCODE_EXTHOST_DISCONNECTED':
1983+ + this.logger.trace('Going offline');
1984+ + this.setOffline();
1985+ + break;
1986+ + case 'VSCODE_EXTHOST_IPC_READY':
1987+ + this.logger.trace('Got ready message');
1988+ + this.sendInitMessage(buffer);
1989+ + break;
1990+ + default:
1991+ + this.logger.error('Unexpected message', field("event", event));
1992+ + break;
19721993+ }
19731994+ });
19741995+
1975- + const listen = (message: IExtHostReadyMessage) => {
1976- + if (message.type === 'VSCODE_EXTHOST_IPC_READY') {
1977- + proc.removeListener('message', listen);
1978- + this.sendInitMessage(buffer);
1979- + }
1980- + };
1981- +
1982- + return proc.on('message', listen);
1996+ + this.logger.trace('Waiting for handshake...');
1997+ + return proc;
19831998+ }
19841999+ }
19852000diff --git a/src/vs/server/node/insights.ts b/src/vs/server/node/insights.ts
@@ -2463,15 +2478,17 @@ index 0000000000000000000000000000000000000000..3d428a57d31f29c40f9c3ce45f715b44
24632478+ };
24642479diff --git a/src/vs/server/node/protocol.ts b/src/vs/server/node/protocol.ts
24652480new file mode 100644
2466- index 0000000000000000000000000000000000000000..3c74512192aec6220216bc8563b3127b9cfd5fbf
2481+ index 0000000000000000000000000000000000000000..0d9310038c0ca378579652d89bc8ac84924213db
24672482--- /dev/null
24682483+++ b/src/vs/server/node/protocol.ts
2469- @@ -0,0 +1,73 @@
2484+ @@ -0,0 +1,91 @@
2485+ + import { field } from '@coder/logger';
24702486+ import * as net from 'net';
24712487+ import { VSBuffer } from 'vs/base/common/buffer';
24722488+ import { PersistentProtocol } from 'vs/base/parts/ipc/common/ipc.net';
24732489+ import { NodeSocket, WebSocketNodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
24742490+ import { AuthRequest, ConnectionTypeRequest, HandshakeMessage } from 'vs/platform/remote/common/remoteAgentConnection';
2491+ + import { logger } from 'vs/server/node/logger';
24752492+
24762493+ export interface SocketOptions {
24772494+ readonly reconnectionToken: string;
@@ -2499,29 +2516,45 @@ index 0000000000000000000000000000000000000000..3c74512192aec6220216bc8563b3127b
24992516+ * Perform a handshake to get a connection request.
25002517+ */
25012518+ public handshake(): Promise<ConnectionTypeRequest> {
2519+ + logger.trace('Protocol handshake', field('token', this.options.reconnectionToken));
25022520+ return new Promise((resolve, reject) => {
2521+ + const timeout = setTimeout(() => {
2522+ + logger.error('Handshake timed out', field('token', this.options.reconnectionToken));
2523+ + reject(new Error("timed out"));
2524+ + }, 10000); // Matches the client timeout.
2525+ +
25032526+ const handler = this.onControlMessage((rawMessage) => {
25042527+ try {
2505- + const message = JSON.parse(rawMessage.toString());
2528+ + const raw = rawMessage.toString();
2529+ + logger.trace('Protocol message', field('token', this.options.reconnectionToken), field('message', raw));
2530+ + const message = JSON.parse(raw);
25062531+ switch (message.type) {
2507- + case 'auth': return this.authenticate(message);
2532+ + case 'auth':
2533+ + return this.authenticate(message);
25082534+ case 'connectionType':
25092535+ handler.dispose();
2536+ + clearTimeout(timeout);
25102537+ return resolve(message);
2511- + default: throw new Error('Unrecognized message type');
2538+ + default:
2539+ + throw new Error('Unrecognized message type');
25122540+ }
25132541+ } catch (error) {
25142542+ handler.dispose();
2543+ + clearTimeout(timeout);
25152544+ reject(error);
25162545+ }
25172546+ });
2547+ +
2548+ + // Kick off the handshake in case we missed the client's opening shot.
2549+ + // TODO: Investigate why that message seems to get lost.
2550+ + this.authenticate();
25182551+ });
25192552+ }
25202553+
25212554+ /**
25222555+ * TODO: This ignores the authentication process entirely for now.
25232556+ */
2524- + private authenticate(_message : AuthRequest): void {
2557+ + private authenticate(_? : AuthRequest): void {
25252558+ this.sendMessage({ type: 'sign', data: '' });
25262559+ }
25272560+
@@ -2542,10 +2575,11 @@ index 0000000000000000000000000000000000000000..3c74512192aec6220216bc8563b3127b
25422575+ }
25432576diff --git a/src/vs/server/node/server.ts b/src/vs/server/node/server.ts
25442577new file mode 100644
2545- index 0000000000000000000000000000000000000000..a1289865858f405f93d3d396f41c6a0aadffd5e5
2578+ index 0000000000000000000000000000000000000000..45a7bf62a6c07d8771b0257e7c98fae095109eb1
25462579--- /dev/null
25472580+++ b/src/vs/server/node/server.ts
2548- @@ -0,0 +1,286 @@
2581+ @@ -0,0 +1,291 @@
2582+ + import { field } from '@coder/logger';
25492583+ import * as fs from 'fs';
25502584+ import * as net from 'net';
25512585+ import * as path from 'path';
@@ -2709,6 +2743,7 @@ index 0000000000000000000000000000000000000000..a1289865858f405f93d3d396f41c6a0a
27092743+ );
27102744+ }
27112745+
2746+ + logger.debug('New connection', field('token', token));
27122747+ protocol.sendMessage(await ok());
27132748+
27142749+ let connection: Connection;
@@ -2727,12 +2762,14 @@ index 0000000000000000000000000000000000000000..a1289865858f405f93d3d396f41c6a0a
27272762+ connection = new ExtensionHostConnection(
27282763+ message.args ? message.args.language : 'en',
27292764+ protocol, buffer, token,
2730- + this.services.get(ILogService) as ILogService,
27312765+ this.services.get(IEnvironmentService) as INativeEnvironmentService,
27322766+ );
27332767+ }
27342768+ connections.set(token, connection);
2735- + connection.onClose(() => connections.delete(token));
2769+ + connection.onClose(() => {
2770+ + logger.debug('Connection closed', field('token', token));
2771+ + connections.delete(token);
2772+ + });
27362773+ this.disposeOldOfflineConnections(connections);
27372774+ break;
27382775+ case ConnectionType.Tunnel: return protocol.tunnel();
@@ -2744,6 +2781,7 @@ index 0000000000000000000000000000000000000000..a1289865858f405f93d3d396f41c6a0a
27442781+ const offline = Array.from(connections.values())
27452782+ .filter((connection) => typeof connection.offline !== 'undefined');
27462783+ for (let i = 0, max = offline.length - this.maxExtraOfflineConnections; i < max; ++i) {
2784+ + logger.debug('Disposing offline connection', field("token", offline[i].token));
27472785+ offline[i].dispose();
27482786+ }
27492787+ }
0 commit comments