Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@supertenant/core / src / tracing / actions.js
Size: Mime:
'use strict';

const { dedupReportError } = require('../logger');
const superconsts = require('@supertenant/superconsts');

/**
 * Default poll wait interval is set to 10 millisecond if not defined by server.
 */
const DefaultWaitPollInterval = 10; // millisecond

/**
 * Ensure that if we're polling, we delay by 1ms at least each time, to prevent from bad configuration coming in from
 * server and causing a busy loop.
 */
const MinWaitPollInterval = 1;

// 24h in seconds
const MaxDelayDuration = 24 * 60 * 60;
/**
 * Default HTTP rejection status code.
 */
const DefaultHttpRejectActionStatusCode = 429;

/**
 * @typedef {{
 *  sqlState: string, sqlMessage: string, errno: number
 * }} SqlRejectActionResult
 */

/** @type {SqlRejectActionResult} */
const DefaultMysqlRejectActionResult = {
    sqlState: '70100',
    sqlMessage: 'Query execution was interrupted [SuperTenant throttling]',
    errno: 1317
};

/**
 * @typedef {{
 *  error_message: string, code: number
 * }} MongodbRejectActionResult
 */

/** @type {MongodbRejectActionResult} */
const DefaultMongodbRejectActionResult = {
    error_message: 'Query execution was interrupted [SuperTenant throttling]',
    code: 11601
};

/**
 * @param {import('@supertenant/superbrain/types/index.cjs').ActionDetails} actionRef
 * @returns {number}
 */
function getDelayDuration(actionRef) {
    if (actionRef.Definition !== null && typeof actionRef.Definition === 'object') {
        /** @type {import('@supertenant/superbrain/types/index.cjs').DelayActionDefinition} */
        // @ts-ignore we do custom type guard in the statements below
        let def = actionRef.Definition;
        const definitionDelayDuration = def.delay_duration;
        if (typeof definitionDelayDuration === 'number' && definitionDelayDuration > 0) {
            let delay = definitionDelayDuration / 1000000; // convert from nano to millisecond
            // sanity check
            if (delay > MaxDelayDuration) {
                return 0;
            }
            if (delay < MinWaitPollInterval) {
                return MinWaitPollInterval;
            }
            return delay;
        }
    }
    return 0;
}

/**
 * @param {import('@supertenant/superbrain/types/index.cjs').ActionDetails} actionRef
 * @returns {number}
 */
function getWaitPollInterval(actionRef) {
    if (actionRef.Definition !== null && typeof actionRef.Definition === 'object') {
        /** @type {import('@supertenant/superbrain/types/index.cjs').WaitActionDefinition} */
        // @ts-ignore we do custom type guard in the statements below
        let def = actionRef.Definition;
        const definitionPollInterval = def.PollInterval;
        if (typeof definitionPollInterval === 'number' && definitionPollInterval > 0) {
            let interval = definitionPollInterval / 1000000; // convert from nano to millisecond
            if (interval < MinWaitPollInterval) {
                return MinWaitPollInterval;
            }
            return interval;
        }
    }
    return DefaultWaitPollInterval;
}

/**
 * @param {import('@supertenant/superbrain/types/index.cjs').ActionDetails} actionRef
 * @returns {number}
 */
function getHttpRejectActionStatusCode(actionRef) {
    if (actionRef.Definition !== null && typeof actionRef.Definition === 'object') {
        /** @type {import('@supertenant/superbrain/types/index.cjs').HttpRejectActionDefinition} */
        // @ts-ignore we do custom type guard in the statements below
        let def = actionRef.Definition;
        const httpReject = def.HttpReject;
        if (httpReject !== null && typeof httpReject === 'object' && httpReject.http_rc !== null) {
            try {
                return typeof httpReject.http_rc === 'number' ? httpReject.http_rc : Number(httpReject.http_rc);
            } catch (e) {
                dedupReportError('actions:HTTP_REJECT_PARSE_CODE', 'failed to parse http status code', e);
            }
        } else if (def[superconsts.RejectAttribute.HttpRc] != null) {
            return typeof def[superconsts.RejectAttribute.HttpRc] === 'number' ? def[superconsts.RejectAttribute.HttpRc] : Number(def[superconsts.RejectAttribute.HttpRc]);
        }
    }
    return DefaultHttpRejectActionStatusCode;
}

/**
 * @param {import('@supertenant/superbrain/types/index.cjs').ActionDetails} actionRef
 * @returns {SqlRejectActionResult}
 */
function getMysqlRejectActionResult(actionRef) {
    if (actionRef.Definition !== null && typeof actionRef.Definition === 'object') {
        /** @type {import('@supertenant/superbrain/types/index.cjs').SqlRejectActionDefinition} */
        // @ts-ignore we do custom type guard in the statements below
        let def = actionRef.Definition;
        const sqlReject = def.SqlReject;
        let errno = 1317;
        let sqlMessage = 'Query execution was interrupted [SuperTenant throttling]';
        let sqlState = '70100';
        if (sqlReject !== null && typeof sqlReject === 'object') {
            if (sqlReject.sql_rc !== null && sqlReject.sql_rc !== undefined) {
                try {
                    errno = typeof sqlReject.sql_rc === 'number' ? sqlReject.sql_rc : Number(sqlReject.sql_rc);
                } catch (e) {
                    dedupReportError('actions:SQL_REJECT_PARSE_ERRNO', 'failed to parse sql errno', e);
                    return DefaultMysqlRejectActionResult;
                }
            }
            sqlMessage = sqlReject.error_message || 'Query execution was interrupted [SuperTenant throttling]';
            sqlState = sqlReject.sql_state || '70100';
        } else if (def[superconsts.RejectAttribute.SqlRc] != null) {
            try {
                errno = typeof def[superconsts.RejectAttribute.SqlRc] === 'number' ? def[superconsts.RejectAttribute.SqlRc] : Number(def[superconsts.RejectAttribute.SqlRc]);
                sqlMessage = def[superconsts.RejectAttribute.ErrorMessage] || 'Query execution was interrupted [SuperTenant throttling]';
                sqlState = def[superconsts.RejectAttribute.SqlState] || '70100';
            } catch (e) {
                dedupReportError('actions:SQL_REJECT_PARSE_ERRNO', 'failed to parse sql errno', e);
                return DefaultMysqlRejectActionResult;
            }
        }
        return {
            errno: errno,
            sqlMessage: sqlMessage,
            sqlState: sqlState
          };
    }
    return DefaultMysqlRejectActionResult;
}

/**
 * @param {import('@supertenant/superbrain/types/index.cjs').ActionDetails} actionRef
 * @returns {MongodbRejectActionResult}
 */
function getMongodbRejectActionResult(actionRef) {
    if (actionRef.Definition !== null && typeof actionRef.Definition === 'object') {
        /** @type {import('@supertenant/superbrain/types/index.cjs').MongodbRejectActionDefinition} */
        // @ts-ignore we do custom type guard in the statements below
        let def = actionRef.Definition;
        const mongodbReject = def.MongodbReject;
        let code = 11601;
        let errorMessage = 'SuperTenant throttled operation';
        if (mongodbReject !== null && typeof mongodbReject === 'object') {
            if (mongodbReject.code !== null && mongodbReject.code !== undefined) {
                try {
                    code = typeof mongodbReject.code === 'number' ? mongodbReject.code : Number(mongodbReject.code);
                } catch (e) {
                    dedupReportError('actions:MONGODB_REJECT_PARSE_ERRNO', 'failed to parse mongodb error code', e);
                    return DefaultMongodbRejectActionResult;
                }
                errorMessage = mongodbReject.error_message || 'SuperTenant throttled operation';
            }
        } else if (def[superconsts.RejectAttribute.Code] != null) {
            try {
                code = typeof def[superconsts.RejectAttribute.Code] === 'number' ? def[superconsts.RejectAttribute.Code] : Number(def[superconsts.RejectAttribute.Code]);
                errorMessage = def[superconsts.RejectAttribute.ErrorMessage] || 'SuperTenant throttled operation';
            } catch (e) {
                dedupReportError('actions:MONGODB_REJECT_PARSE_ERRNO', 'failed to parse mongodb error code', e);
                return DefaultMongodbRejectActionResult;
            }
        }
        return {
            code: code,
            error_message: errorMessage
          };
    }
    return DefaultMongodbRejectActionResult;
}

module.exports = {
    getDelayDuration,
    getWaitPollInterval,
    getHttpRejectActionStatusCode,
    getMysqlRejectActionResult,
    getMongodbRejectActionResult
};