async handleGetConfig()

in functions/source/faz-handler/lib/aws/index.js [2582:2729]


    async handleGetConfig() {
        logger.info('calling handleGetConfig');
        let config,
            primaryInfo,
            params = {},
            primaryIp,
            duplicatedGetConfigCall;

        let promiseEmitter = this.checkPrimaryElection.bind(this),
            validator = result => {
                // TODO: remove the workaround if mantis item: #0534971 is resolved
                // if i am the primary, don't wait, continue, if not, wait
                // this if-condition is to work around the double GET config calls.
                if (
                    this._primaryRecord &&
                    this._primaryRecord.voteState === 'pending' &&
                    this._selfInstance &&
                    this._primaryRecord.instanceId === this._selfInstance.instanceId &&
                    this._primaryRecord.scalingGroupName === this.scalingGroupName
                ) {
                    duplicatedGetConfigCall = true;
                    primaryIp = this._primaryRecord.ip;
                    return true;
                }

                // if neither a pending primary nor a primary instance is found on the primary
                // scaling group. and if primary-election-no-wait is enabled, allow this fgt
                // to wake up without a primary ip.
                // this also implies this instance cannot be elected as the next primary which
                // means it should be a secondary.

                // primary info exists
                if (result) {
                    // i am the elected primary
                    if (
                        result.primaryPrivateIpAddress ===
                        this._selfInstance.primaryPrivateIpAddress
                    ) {
                        primaryIp = this._selfInstance.primaryPrivateIpAddress;
                        return true;
                    } else if (this._primaryRecord) {
                        // i am not the elected primary, how is the primary election going?
                        if (this._primaryRecord.voteState === 'done') {
                            // primary election done
                            return true;
                        } else if (this._primaryRecord.voteState === 'pending') {
                            // primary is still pending
                            // if not wait for the primary election to complete,
                            if (this._settings['primary-election-no-wait'] === 'true') {
                                return true;
                            } else {
                                // primary election not done, wait for a moment
                                // clear the current primary record cache and get a new one
                                // in the next call
                                this._primaryRecord = null;
                                return false;
                            }
                        }
                    } else {
                        // primary info exists but no primary record?
                        // this looks like a case that shouldn't happen. do the election again?
                        logger.warn('primary info found but primary record not found. retry.');
                        return false;
                    }
                } else {
                    // primary cannot be elected but I cannot be the next elected primary either
                    // if not wait for the primary election to complete, let me become headless
                    return this._settings['primary-election-no-wait'] === 'true';
                }
            },
            counter = () => {
                if (Date.now() < process.env.SCRIPT_EXECUTION_EXPIRE_TIME - 3000) {
                    return false;
                }
                logger.warn('script execution is about to expire');
                return true;
            };

        try {
            primaryInfo = await AutoScaleCore.Functions.waitFor(
                promiseEmitter,
                validator,
                5000,
                counter
            );
        } catch (error) {
            // if error occurs, check who is holding a primary election, if it is this instance,
            // terminates this election. then tear down this instance whether it's primary or not.
            this._primaryRecord = this._primaryRecord || (await this.platform.getPrimaryRecord());
            if (
                this._primaryRecord.instanceId === this._selfInstance.instanceId &&
                this._primaryRecord.scalingGroupName === this._selfInstance.scalingGroupName
            ) {
                await this.platform.removePrimaryRecord();
            }
            await this.removeInstance(this._selfInstance);
            throw new Error(
                'Failed to determine the primary instance. This instance is unable' +
                    ' to bootstrap. Please report this to' +
                    ' administrators.'
            );
        }

        // get TGW_VPN record
        if (this._settings['enable-transit-gateway-vpn'] === 'true') {
            let vpnAttachmentRecord = await this.platform.getTgwVpnAttachmentRecord(
                this._selfInstance
            );
            if (vpnAttachmentRecord) {
                params.vpnConfigSetName = 'setuptgwvpn';
                params.vpnConfiguration =
                    vpnAttachmentRecord.customerGatewayConfiguration.vpn_connection;
                params.vpnConfiguration.id = params.vpnConfiguration.$.id;
            }
        }

        // the primary ip same as mine? (diagram: primary IP same as mine?)
        // this checking for 'duplicatedGetConfigCall' is to work around
        // the double GET config calls.
        // TODO: remove the workaround if mantis item: #0534971 is resolved
        if (duplicatedGetConfigCall || primaryIp === this._selfInstance.primaryPrivateIpAddress) {
            this._step = 'handler:getConfig:getPrimaryConfig';
            params.callbackUrl = await this.platform.getCallbackEndpointUrl();
            config = await this.getPrimaryConfig(params);
            logger.info(
                'called handleGetConfig: returning primary config' +
                    `(master-ip: ${primaryIp}):\n ${config}`
            );
            return config;
        } else {
            this._step = 'handler:getConfig:getSecondaryConfig';
            let getPendingPrimaryIp = !(
                this._settings['primary-election-no-wait'] === 'true' &&
                this._primaryRecord &&
                this._primaryRecord.voteState === 'pending'
            );
            params.callbackUrl = await this.platform.getCallbackEndpointUrl();
            params.primaryIp =
                (getPendingPrimaryIp && primaryInfo && primaryInfo.primaryPrivateIpAddress) || null;
            params.allowHeadless = this._settings['primary-election-no-wait'] === 'true';
            config = await this.getSecondaryConfig(params);
            logger.info(
                'called handleGetConfig: returning secondary config' +
                    `(master-ip: ${params.primaryIp || 'undetermined'}):\n ${config}`
            );
            return config;
        }
    }