chore(vscode): update to 1.53.2

These conflicts will be resolved in the following commits. We do it this way so
that PR review is possible.
This commit is contained in:
Joe Previte
2021-02-25 11:27:27 -07:00
1900 changed files with 83066 additions and 64589 deletions

View File

@@ -8,7 +8,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
import { Disposable } from 'vs/base/common/lifecycle';
import { VSBuffer } from 'vs/base/common/buffer';
import { Emitter } from 'vs/base/common/event';
import { Emitter, Event } from 'vs/base/common/event';
import { RemoteAuthorityResolverError } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
import { ISignService } from 'vs/platform/sign/common/sign';
@@ -86,6 +86,7 @@ export interface ISocketFactory {
connect(host: string, port: number, query: string, callback: IConnectCallback): void;
}
<<<<<<< HEAD
async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptions, connectionType: ConnectionType, args: any | undefined): Promise<{ protocol: PersistentProtocol; ownsProtocol: boolean; }> {
const logPrefix = connectLogPrefix(options, connectionType);
const { protocol, ownsProtocol } = await new Promise<{ protocol: PersistentProtocol; ownsProtocol: boolean; }>((c, e) => {
@@ -101,81 +102,126 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio
e(err);
return;
}
=======
async function readOneControlMessage<T>(protocol: PersistentProtocol): Promise<T> {
const raw = await Event.toPromise(protocol.onControlMessage);
const msg = JSON.parse(raw.toString());
const error = getErrorFromMessage(msg);
if (error) {
throw error;
}
return msg;
}
>>>>>>> 89b6e0164fa770333755b11504e19a4232b1a2d4
options.logService.trace(`${logPrefix} 2/6. socketFactory.connect() was successful.`);
if (options.reconnectionProtocol) {
options.reconnectionProtocol.beginAcceptReconnection(socket, null);
c({ protocol: options.reconnectionProtocol, ownsProtocol: false });
} else {
c({ protocol: new PersistentProtocol(socket, null), ownsProtocol: true });
}
function waitWithTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {
return new Promise<T>((resolve, reject) => {
const timeoutToken = setTimeout(() => {
const error: any = new Error('Timeout');
error.code = 'ETIMEDOUT';
error.syscall = 'connect';
reject(error);
}, timeout);
promise.then(
(result) => {
clearTimeout(timeoutToken);
resolve(result);
},
(error) => {
clearTimeout(timeoutToken);
reject(error);
}
);
});
}
return new Promise<{ protocol: PersistentProtocol; ownsProtocol: boolean; }>((c, e) => {
function createSocket(socketFactory: ISocketFactory, host: string, port: number, query: string): Promise<ISocket> {
return new Promise<ISocket>((resolve, reject) => {
socketFactory.connect(host, port, query, (err: any, socket: ISocket | undefined) => {
if (err || !socket) {
return reject(err);
}
resolve(socket);
});
});
}
const errorTimeoutToken = setTimeout(() => {
const error: any = new Error('handshake timeout');
error.code = 'ETIMEDOUT';
error.syscall = 'connect';
async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptions, connectionType: ConnectionType, args: any | undefined): Promise<{ protocol: PersistentProtocol; ownsProtocol: boolean; }> {
const logPrefix = connectLogPrefix(options, connectionType);
options.logService.trace(`${logPrefix} 1/6. invoking socketFactory.connect().`);
let socket: ISocket;
try {
socket = await createSocket(options.socketFactory, options.host, options.port, `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`);
} catch (error) {
options.logService.error(`${logPrefix} socketFactory.connect() failed. Error:`);
options.logService.error(error);
throw error;
}
options.logService.trace(`${logPrefix} 2/6. socketFactory.connect() was successful.`);
let protocol: PersistentProtocol;
let ownsProtocol: boolean;
if (options.reconnectionProtocol) {
options.reconnectionProtocol.beginAcceptReconnection(socket, null);
protocol = options.reconnectionProtocol;
ownsProtocol = false;
} else {
protocol = new PersistentProtocol(socket, null);
ownsProtocol = true;
}
options.logService.trace(`${logPrefix} 3/6. sending AuthRequest control message.`);
const authRequest: AuthRequest = {
type: 'auth',
auth: options.connectionToken || '00000000000000000000'
};
protocol.sendControl(VSBuffer.fromString(JSON.stringify(authRequest)));
try {
const msg = await waitWithTimeout(readOneControlMessage<HandshakeMessage>(protocol), 10000);
if (msg.type !== 'sign' || typeof msg.data !== 'string') {
const error: any = new Error('Unexpected handshake message');
error.code = 'VSCODE_CONNECTION_ERROR';
throw error;
}
options.logService.trace(`${logPrefix} 4/6. received SignRequest control message.`);
const signed = await options.signService.sign(msg.data);
const connTypeRequest: ConnectionTypeRequest = {
type: 'connectionType',
commit: options.commit,
signedData: signed,
desiredConnectionType: connectionType
};
if (args) {
connTypeRequest.args = args;
}
options.logService.trace(`${logPrefix} 5/6. sending ConnectionTypeRequest control message.`);
protocol.sendControl(VSBuffer.fromString(JSON.stringify(connTypeRequest)));
return { protocol, ownsProtocol };
} catch (error) {
if (error && error.code === 'ETIMEDOUT') {
options.logService.error(`${logPrefix} the handshake took longer than 10 seconds. Error:`);
options.logService.error(error);
if (ownsProtocol) {
safeDisposeProtocolAndSocket(protocol);
}
e(error);
}, 10000);
const messageRegistration = protocol.onControlMessage(async raw => {
const msg = <HandshakeMessage>JSON.parse(raw.toString());
// Stop listening for further events
messageRegistration.dispose();
const error = getErrorFromMessage(msg);
if (error) {
options.logService.error(`${logPrefix} received error control message when negotiating connection. Error:`);
options.logService.error(error);
if (ownsProtocol) {
safeDisposeProtocolAndSocket(protocol);
}
return e(error);
}
if (msg.type === 'sign') {
options.logService.trace(`${logPrefix} 4/6. received SignRequest control message.`);
const signed = await options.signService.sign(msg.data);
const connTypeRequest: ConnectionTypeRequest = {
type: 'connectionType',
commit: options.commit,
signedData: signed,
desiredConnectionType: connectionType
};
if (args) {
connTypeRequest.args = args;
}
options.logService.trace(`${logPrefix} 5/6. sending ConnectionTypeRequest control message.`);
protocol.sendControl(VSBuffer.fromString(JSON.stringify(connTypeRequest)));
clearTimeout(errorTimeoutToken);
c({ protocol, ownsProtocol });
} else {
const error = new Error('handshake error');
options.logService.error(`${logPrefix} received unexpected control message. Error:`);
options.logService.error(error);
if (ownsProtocol) {
safeDisposeProtocolAndSocket(protocol);
}
e(error);
}
});
options.logService.trace(`${logPrefix} 3/6. sending AuthRequest control message.`);
const authRequest: AuthRequest = {
type: 'auth',
auth: options.connectionToken || '00000000000000000000'
};
protocol.sendControl(VSBuffer.fromString(JSON.stringify(authRequest)));
});
}
if (error && error.code === 'VSCODE_CONNECTION_ERROR') {
options.logService.error(`${logPrefix} received error control message when negotiating connection. Error:`);
options.logService.error(error);
}
if (ownsProtocol) {
safeDisposeProtocolAndSocket(protocol);
}
throw error;
}
}
interface IManagementConnectionResult {
@@ -287,7 +333,7 @@ export async function connectRemoteAgentManagement(options: IConnectionOptions,
} catch (err) {
options.logService.error(`[remote-connection] An error occurred in the very first connect attempt, it will be treated as a permanent error! Error:`);
options.logService.error(err);
PersistentConnection.triggerPermanentFailure();
PersistentConnection.triggerPermanentFailure(0, 0, RemoteAuthorityResolverError.isHandled(err));
throw err;
}
}
@@ -301,7 +347,7 @@ export async function connectRemoteAgentExtensionHost(options: IConnectionOption
} catch (err) {
options.logService.error(`[remote-connection] An error occurred in the very first connect attempt, it will be treated as a permanent error! Error:`);
options.logService.error(err);
PersistentConnection.triggerPermanentFailure();
PersistentConnection.triggerPermanentFailure(0, 0, RemoteAuthorityResolverError.isHandled(err));
throw err;
}
}
@@ -333,10 +379,16 @@ export const enum PersistentConnectionEventType {
}
export class ConnectionLostEvent {
public readonly type = PersistentConnectionEventType.ConnectionLost;
constructor(
public readonly reconnectionToken: string,
public readonly millisSinceLastIncomingData: number
) { }
}
export class ReconnectionWaitEvent {
public readonly type = PersistentConnectionEventType.ReconnectionWait;
constructor(
public readonly reconnectionToken: string,
public readonly millisSinceLastIncomingData: number,
public readonly durationSeconds: number,
private readonly cancellableTimer: CancelablePromise<void>,
public readonly connectionAttempt: number
@@ -348,22 +400,44 @@ export class ReconnectionWaitEvent {
}
export class ReconnectionRunningEvent {
public readonly type = PersistentConnectionEventType.ReconnectionRunning;
constructor(
public readonly reconnectionToken: string,
public readonly millisSinceLastIncomingData: number,
public readonly attempt: number
) { }
}
export class ConnectionGainEvent {
public readonly type = PersistentConnectionEventType.ConnectionGain;
constructor(
public readonly reconnectionToken: string,
public readonly millisSinceLastIncomingData: number,
public readonly attempt: number
) { }
}
export class ReconnectionPermanentFailureEvent {
public readonly type = PersistentConnectionEventType.ReconnectionPermanentFailure;
constructor(
public readonly reconnectionToken: string,
public readonly millisSinceLastIncomingData: number,
public readonly attempt: number,
public readonly handled: boolean
) { }
}
export type PersistentConnectionEvent = ConnectionGainEvent | ConnectionLostEvent | ReconnectionWaitEvent | ReconnectionRunningEvent | ReconnectionPermanentFailureEvent;
abstract class PersistentConnection extends Disposable {
public static triggerPermanentFailure(): void {
public static triggerPermanentFailure(millisSinceLastIncomingData: number, attempt: number, handled: boolean): void {
this._permanentFailure = true;
this._instances.forEach(instance => instance._gotoPermanentFailure());
this._permanentFailureMillisSinceLastIncomingData = millisSinceLastIncomingData;
this._permanentFailureAttempt = attempt;
this._permanentFailureHandled = handled;
this._instances.forEach(instance => instance._gotoPermanentFailure(this._permanentFailureMillisSinceLastIncomingData, this._permanentFailureAttempt, this._permanentFailureHandled));
}
private static _permanentFailure: boolean = false;
private static _permanentFailureMillisSinceLastIncomingData: number = 0;
private static _permanentFailureAttempt: number = 0;
private static _permanentFailureHandled: boolean = false;
private static _instances: PersistentConnection[] = [];
private readonly _onDidStateChange = this._register(new Emitter<PersistentConnectionEvent>());
@@ -382,7 +456,7 @@ abstract class PersistentConnection extends Disposable {
this.protocol = protocol;
this._isReconnecting = false;
this._onDidStateChange.fire(new ConnectionGainEvent());
this._onDidStateChange.fire(new ConnectionGainEvent(this.reconnectionToken, 0, 0));
this._register(protocol.onSocketClose(() => this._beginReconnecting()));
this._register(protocol.onSocketTimeout(() => this._beginReconnecting()));
@@ -390,7 +464,7 @@ abstract class PersistentConnection extends Disposable {
PersistentConnection._instances.push(this);
if (PersistentConnection._permanentFailure) {
this._gotoPermanentFailure();
this._gotoPermanentFailure(PersistentConnection._permanentFailureMillisSinceLastIncomingData, PersistentConnection._permanentFailureAttempt, PersistentConnection._permanentFailureHandled);
}
}
@@ -414,14 +488,15 @@ abstract class PersistentConnection extends Disposable {
}
const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true);
this._options.logService.info(`${logPrefix} starting reconnecting loop. You can get more information with the trace log level.`);
this._onDidStateChange.fire(new ConnectionLostEvent());
const TIMES = [5, 5, 10, 10, 10, 10, 10, 30];
this._onDidStateChange.fire(new ConnectionLostEvent(this.reconnectionToken, this.protocol.getMillisSinceLastIncomingData()));
const TIMES = [0, 5, 5, 10, 10, 10, 10, 10, 30];
const disconnectStartTime = Date.now();
let attempt = -1;
do {
attempt++;
const waitTime = (attempt < TIMES.length ? TIMES[attempt] : TIMES[TIMES.length - 1]);
try {
<<<<<<< HEAD
const sleepPromise = sleep(waitTime);
this._onDidStateChange.fire(new ReconnectionWaitEvent(waitTime, sleepPromise, attempt+1));
@@ -429,6 +504,17 @@ abstract class PersistentConnection extends Disposable {
try {
await sleepPromise;
} catch { } // User canceled timer
=======
if (waitTime > 0) {
const sleepPromise = sleep(waitTime);
this._onDidStateChange.fire(new ReconnectionWaitEvent(this.reconnectionToken, this.protocol.getMillisSinceLastIncomingData(), waitTime, sleepPromise));
this._options.logService.info(`${logPrefix} waiting for ${waitTime} seconds before reconnecting...`);
try {
await sleepPromise;
} catch { } // User canceled timer
}
>>>>>>> 89b6e0164fa770333755b11504e19a4232b1a2d4
if (PersistentConnection._permanentFailure) {
this._options.logService.error(`${logPrefix} permanent failure occurred while running the reconnecting loop.`);
@@ -436,26 +522,26 @@ abstract class PersistentConnection extends Disposable {
}
// connection was lost, let's try to re-establish it
this._onDidStateChange.fire(new ReconnectionRunningEvent());
this._onDidStateChange.fire(new ReconnectionRunningEvent(this.reconnectionToken, this.protocol.getMillisSinceLastIncomingData(), attempt + 1));
this._options.logService.info(`${logPrefix} resolving connection...`);
const simpleOptions = await resolveConnectionOptions(this._options, this.reconnectionToken, this.protocol);
this._options.logService.info(`${logPrefix} connecting to ${simpleOptions.host}:${simpleOptions.port}...`);
await connectWithTimeLimit(simpleOptions.logService, this._reconnect(simpleOptions), RECONNECT_TIMEOUT);
this._options.logService.info(`${logPrefix} reconnected!`);
this._onDidStateChange.fire(new ConnectionGainEvent());
this._onDidStateChange.fire(new ConnectionGainEvent(this.reconnectionToken, this.protocol.getMillisSinceLastIncomingData(), attempt + 1));
break;
} catch (err) {
if (err.code === 'VSCODE_CONNECTION_ERROR') {
this._options.logService.error(`${logPrefix} A permanent error occurred in the reconnecting loop! Will give up now! Error:`);
this._options.logService.error(err);
PersistentConnection.triggerPermanentFailure();
PersistentConnection.triggerPermanentFailure(this.protocol.getMillisSinceLastIncomingData(), attempt + 1, false);
break;
}
if (Date.now() - disconnectStartTime > ProtocolConstants.ReconnectionGraceTime) {
this._options.logService.error(`${logPrefix} An error occurred while reconnecting, but it will be treated as a permanent error because the reconnection grace time has expired! Will give up now! Error:`);
this._options.logService.error(err);
PersistentConnection.triggerPermanentFailure();
PersistentConnection.triggerPermanentFailure(this.protocol.getMillisSinceLastIncomingData(), attempt + 1, false);
break;
}
if (RemoteAuthorityResolverError.isTemporarilyNotAvailable(err)) {
@@ -476,16 +562,22 @@ abstract class PersistentConnection extends Disposable {
// try again!
continue;
}
if (err instanceof RemoteAuthorityResolverError) {
this._options.logService.error(`${logPrefix} A RemoteAuthorityResolverError occurred while trying to reconnect. Will give up now! Error:`);
this._options.logService.error(err);
PersistentConnection.triggerPermanentFailure(this.protocol.getMillisSinceLastIncomingData(), attempt + 1, RemoteAuthorityResolverError.isHandled(err));
break;
}
this._options.logService.error(`${logPrefix} An unknown error occurred while trying to reconnect, since this is an unknown case, it will be treated as a permanent error! Will give up now! Error:`);
this._options.logService.error(err);
PersistentConnection.triggerPermanentFailure();
PersistentConnection.triggerPermanentFailure(this.protocol.getMillisSinceLastIncomingData(), attempt + 1, false);
break;
}
} while (!PersistentConnection._permanentFailure);
}
private _gotoPermanentFailure(): void {
this._onDidStateChange.fire(new ReconnectionPermanentFailureEvent());
private _gotoPermanentFailure(millisSinceLastIncomingData: number, attempt: number, handled: boolean): void {
this._onDidStateChange.fire(new ReconnectionPermanentFailureEvent(this.reconnectionToken, millisSinceLastIncomingData, attempt, handled));
safeDisposeProtocolAndSocket(this.protocol);
}