diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index d8280c007..3adb3eaa2 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -982,7 +982,7 @@ function createParameters() }, { name: PARAM_RETRY_SF_MAX_SLEEP_TIME, - defaultValue: 108, + defaultValue: 16, validate: isNonNegativeNumber } ]; diff --git a/lib/services/sf.js b/lib/services/sf.js index 6334b86b6..2aa63103c 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -1180,10 +1180,10 @@ StateConnecting.prototype.continue = function () Date.now() : 'FIXEDTIMESTAMP'; const maxLoginRetries = connectionConfig.getRetrySfMaxLoginRetries(); const maxLoginTimeout = connectionConfig.getLoginTimeout(); - let sleep = connectionConfig.getRetrySfStartingSleepTime(); - let totalTimeout = sleep; - const cap = connectionConfig.getRetrySfMaxSleepTime(); - Logger.getInstance().debug("Retry Max sleep time = " + cap); + const base = connectionConfig.getRetrySfStartingSleepTime(); + let sleep = base; + let totalTimeout = base; + Logger.getInstance().debug("Total loginTimeout is for the retries = " + maxLoginTimeout); const parent = this; const requestCallback = function (err, body) { @@ -1217,9 +1217,14 @@ StateConnecting.prototype.continue = function () totalTimeout < maxLoginTimeout) { numRetries++; - const jitter = Util.jitteredSleepTime(numRetries, sleep, totalTimeout, maxLoginTimeout); + const jitter = Util.jitteredSleepTime(numRetries, sleep, totalTimeout, base, maxLoginTimeout); sleep = jitter.sleep; totalTimeout = jitter.totalTimeout; + + if(sleep <= 0) { + Logger.getInstance().debug("Reached out to the Login Timeout"); + parent.snowflakeService.transitionToDisconnected(); + } setTimeout(sendRequest, sleep * 1000); return; } diff --git a/lib/util.js b/lib/util.js index 01b6b62e3..dc7921fd5 100644 --- a/lib/util.js +++ b/lib/util.js @@ -426,14 +426,14 @@ exports.nextSleepTime = function ( * * @param {Number} numofRetries * @param {Number} currentSleepTime - * @param {Number} maxSleepTime + * @param {Number} totalTimeout + * @param {Number} base + * @param {Number} maxLoginTimeout * @returns {JSON} return next sleep Time and totalTime. */ -exports.jitteredSleepTime = function (numofRetries, currentSleepTime, totalTimeout, maxLoginTimeout) { - const nextSleepTime = Math.min(maxLoginTimeout - totalTimeout, 4 * numofRetries); - const sleep = nextSleepTime + getJitter(currentSleepTime); +exports.jitteredSleepTime = function (numofRetries, currentSleepTime, totalTimeout, base, maxLoginTimeout) { + const sleep = Math.min((maxLoginTimeout - totalTimeout), getNextSleepTime(numofRetries, base, currentSleepTime) ); totalTimeout += sleep - return {sleep, totalTimeout} } @@ -455,14 +455,17 @@ exports.chooseRandom = chooseRandom; /** * return the jitter value. - * - * @param {Number} curWaitTime + * @param {Number} numofRetries + * @param {Number} base + * @param {Number} currentSleepTime * @returns {Boolean} return jitter. */ -function getJitter (curWaitTime) { +function getNextSleepTime (numofRetries, base, currentSleepTime) { const multiplicationFactor = chooseRandom(1, -1); - const jitterAmount = 0.5 * curWaitTime * multiplicationFactor; - return jitterAmount; + const nextSleep = (base * (2 ** (numofRetries - 1))); + const jitterAmount = 0.5 * currentSleepTime * multiplicationFactor; + + return nextSleep + jitterAmount; } /** diff --git a/test/unit/util_test.js b/test/unit/util_test.js index 7ef205aaa..8c9941aca 100644 --- a/test/unit/util_test.js +++ b/test/unit/util_test.js @@ -600,31 +600,27 @@ describe('Util', function () retry403: false, isRetryable: true, }, - { - statusCode: 525, - retry403: false, - isRetryable: true, - }, ]; const maxLoginTimeout = 300; - let currentSleepTime = 4; + const base = 4; + let currentSleepTime = base; let retryCount = 1; - let totalTimeout = 1; + let totalTimeout = base; for (const response of errorCodes) { + retryCount++; assert.strictEqual(Util.isRetryableHttpError(response,true), true); - const result = Util.jitteredSleepTime(retryCount, currentSleepTime, totalTimeout, maxLoginTimeout); + const result = Util.jitteredSleepTime(retryCount, currentSleepTime, totalTimeout, base, maxLoginTimeout); const jitter = currentSleepTime / 2 - const nextSleep = 2 ** retryCount; + const nextSleep = base * (2 ** (retryCount-1)); currentSleepTime = result.sleep; totalTimeout = result.totalTimeout; assert.ok(currentSleepTime <= nextSleep + jitter || currentSleepTime >= nextSleep - jitter) - retryCount++; } - assert.strictEqual(retryCount, 8); + assert.strictEqual(retryCount, 7); assert.ok(totalTimeout <= maxLoginTimeout); });