Repository URL to install this package:
|
Version:
0.9.2-rc0 ▾
|
'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
};