From c4f2a41464afd29ae9b583182343604f610ae177 Mon Sep 17 00:00:00 2001 From: Johan Van den Brande Date: Thu, 26 Nov 2020 17:39:58 +0100 Subject: [PATCH 1/2] Add failover handling --- index.d.ts | 4 ++++ index.js | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 5ce24c0..80e01b8 100644 --- a/index.d.ts +++ b/index.d.ts @@ -87,6 +87,10 @@ declare namespace serverlessMysql { * Integer The minimum number of seconds that a connection must be idle before the module will recycle it. 3 */ zombieMinTimeout?: number + /** + * Boolean Handle a failover with a DNS switchover gracefully. Defaults to false. + */ + handleFailover?: boolean } class Transaction { diff --git a/index.js b/index.js index 2806850..f15aeba 100644 --- a/index.js +++ b/index.js @@ -36,7 +36,7 @@ module.exports = (params) => { // Init setting values let MYSQL, manageConns, cap, base, maxRetries, connUtilization, backoff, zombieMinTimeout, zombieMaxTimeout, maxConnsFreq, usedConnsFreq, - onConnect, onConnectError, onRetry, onClose, onError, onKill, onKillError, PromiseLibrary + onConnect, onConnectError, onRetry, onClose, onError, onKill, onKillError, PromiseLibrary, handlFailover /********************************************************************/ /** HELPER/CONVENIENCE FUNCTIONS **/ @@ -187,7 +187,9 @@ module.exports = (params) => { // If no args are passed in a transaction, ignore query if (this && this.rollback && args.length === 0) { return resolve([]) } client.query(...args, async (err, results) => { - if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') { + if (err && (err.code === 'PROTOCOL_SEQUENCE_TIMEOUT' + || (handlFailover && err.code === 'ER_OPTION_PREVENTS_STATEMENT')) + ) { client.destroy() // destroy connection on timeout resetClient() // reset the client reject(err) // reject the promise with the error @@ -366,6 +368,7 @@ module.exports = (params) => { zombieMaxTimeout = Number.isInteger(cfg.zombieMaxTimeout) ? cfg.zombieMaxTimeout : 60*15 // default to 15 minutes maxConnsFreq = Number.isInteger(cfg.maxConnsFreq) ? cfg.maxConnsFreq : 15*1000 // default to 15 seconds usedConnsFreq = Number.isInteger(cfg.usedConnsFreq) ? cfg.usedConnsFreq : 0 // default to 0 ms + handlFailover = cfg.handleFailover === true ? true : false // default to false // Event handlers onConnect = typeof cfg.onConnect === 'function' ? cfg.onConnect : () => {} From 1facb6ca5a3035ba5317a82831403506ff45413c Mon Sep 17 00:00:00 2001 From: Johan Van den Brande Date: Fri, 27 Nov 2020 08:46:18 +0100 Subject: [PATCH 2/2] Fix typo in variable name --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index f15aeba..9713301 100644 --- a/index.js +++ b/index.js @@ -36,7 +36,7 @@ module.exports = (params) => { // Init setting values let MYSQL, manageConns, cap, base, maxRetries, connUtilization, backoff, zombieMinTimeout, zombieMaxTimeout, maxConnsFreq, usedConnsFreq, - onConnect, onConnectError, onRetry, onClose, onError, onKill, onKillError, PromiseLibrary, handlFailover + onConnect, onConnectError, onRetry, onClose, onError, onKill, onKillError, PromiseLibrary, handleFailover /********************************************************************/ /** HELPER/CONVENIENCE FUNCTIONS **/ @@ -188,7 +188,7 @@ module.exports = (params) => { if (this && this.rollback && args.length === 0) { return resolve([]) } client.query(...args, async (err, results) => { if (err && (err.code === 'PROTOCOL_SEQUENCE_TIMEOUT' - || (handlFailover && err.code === 'ER_OPTION_PREVENTS_STATEMENT')) + || (handleFailover && err.code === 'ER_OPTION_PREVENTS_STATEMENT')) ) { client.destroy() // destroy connection on timeout resetClient() // reset the client @@ -368,7 +368,7 @@ module.exports = (params) => { zombieMaxTimeout = Number.isInteger(cfg.zombieMaxTimeout) ? cfg.zombieMaxTimeout : 60*15 // default to 15 minutes maxConnsFreq = Number.isInteger(cfg.maxConnsFreq) ? cfg.maxConnsFreq : 15*1000 // default to 15 seconds usedConnsFreq = Number.isInteger(cfg.usedConnsFreq) ? cfg.usedConnsFreq : 0 // default to 0 ms - handlFailover = cfg.handleFailover === true ? true : false // default to false + handleFailover = cfg.handleFailover === true ? true : false // default to false // Event handlers onConnect = typeof cfg.onConnect === 'function' ? cfg.onConnect : () => {}