src/vs/platform/remote/common/remoteAgentConnection.ts/PersistentConnection/constructor
class PersistentConnection:	constructor(private readonly _connectionType: ConnectionType, options: IConnectionOptions, reconnectionToken: string, protocol: PersistentProtocol) {
		super();
		this._options = options;
		this.reconnectionToken = reconnectionToken;
		this.protocol = protocol;
		this._isReconnecting = false;

		this._onDidStateChange.fire(new ConnectionGainEvent(this.reconnectionToken, 0, 0));

		this._register(protocol.onSocketClose((e) => {
			const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true);
			if (!e) {
				this._options.logService.info(`${logPrefix} received socket close event.`);
			} else if (e.type === SocketCloseEventType.NodeSocketCloseEvent) {
				this._options.logService.info(`${logPrefix} received socket close event (hadError: ${e.hadError}).`);
				if (e.error) {
					this._options.logService.error(e.error);
				}
			} else {
				this._options.logService.info(`${logPrefix} received socket close event (wasClean: ${e.wasClean}, code: ${e.code}, reason: ${e.reason}).`);
				if (e.event) {
					this._options.logService.error(e.event);
				}
			}
			this._beginReconnecting();
		}));
		this._register(protocol.onSocketTimeout(() => {
			const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true);
			this._options.logService.trace(`${logPrefix} received socket timeout event.`);
			this._beginReconnecting();
		}));

		PersistentConnection._instances.push(this);

		if (PersistentConnection._permanentFailure) {
			this._gotoPermanentFailure(PersistentConnection._permanentFailureMillisSinceLastIncomingData, PersistentConnection._permanentFailureAttempt, PersistentConnection._permanentFailureHandled);
		}
	}