async __connect()

in aws-greengrass-core-sdk/stream-manager/client.js [129:214]


    async __connect() {
        try {
            await new Promise((resolve, reject) => {
                if (this.#closed) {
                    return reject(new exceptions.StreamManagerException('Client is closed and cannot be reopened'));
                }
                if (this.#connected) {
                    return resolve();
                }

                const newSock = net.createConnection({
                    port: this.port,
                    host: this.host,
                    // Set high water mark so that we can read 1 full packet (1GB) at a time instead of needing to
                    // try to read multiple times and combine the results. The HWM adjusts how much the socket will
                    // buffer when reading.
                    readableHighWaterMark: utilInternal.MAX_PACKET_SIZE,
                }, async () => {
                    try {
                        // Connection started
                        this.#logger.debug(`Opening connection to ${this.host}:${this.port}`);
                        this.#connected = false;

                        const request = new smData.ConnectRequest()
                            .withProtocolVersion(smData.VersionInfo.PROTOCOL_VERSION.asMap())
                            .withSdkVersion(SDK_VERSION)
                            .withAuthToken(this.#authToken)
                            .withOtherSupportedProtocolVersions(OLD_SUPPORTED_PROTOCOL_VERSIONS)
                            .withRequestId(utilInternal.uuidv4());

                        // Write the connect version
                        newSock.write(utilInternal.intToBuffer(CONNECT_VERSION, 1));

                        // Write request to socket
                        const frame = new smData.MessageFrame(smData.Operation.Connect, cbor.encode(request.asMap()));
                        const byteFrame = utilInternal.encodeFrame(frame);
                        newSock.write(byteFrame.header);
                        newSock.write(byteFrame.payload);

                        await this.__read(newSock);
                        // Only now that we're connected should we set/replace the socket
                        this.#socket = newSock;
                        resolve();
                    } catch (errors) {
                        reject(errors);
                    }
                });

                newSock.on('error', (e) => {
                    this.#logger.error(e);
                    this.errorCallbacks.forEach((f) => f(e));
                    newSock.end();

                    if (!this.#connected) {
                        reject(e);
                    }
                });

                newSock.on('end', () => {
                    this.#logger.info('Socket is ending');
                });

                newSock.on('close', () => {
                    newSock.destroy();
                    this.#connected = false;
                });
            });

            // Set us to be in connected mode
            this.#connected = true;
            this.#logger.info('Successfully connected');
            this.connectCallbacks.forEach((f) => {
                try {
                    f();
                } finally {
                    // After calling the connect callback remove it so we don't call it multiple times.
                    // A client should only connect once.
                    removeFromArray(this.connectCallbacks, f);
                }
            });
        } catch (e) {
            this.#logger.error(e);
            this.errorCallbacks.forEach((f) => f(e));
            throw e;
        }
    }