diff --git a/packages/pg/lib/client.js b/packages/pg/lib/client.js index 077a9f676..93807e48c 100644 --- a/packages/pg/lib/client.js +++ b/packages/pg/lib/client.js @@ -371,6 +371,9 @@ Client.prototype.getStartupConf = function () { if (params.statement_timeout) { data.statement_timeout = String(parseInt(params.statement_timeout, 10)) } + if (params.idle_in_transaction_session_timeout) { + data.idle_in_transaction_session_timeout = String(parseInt(params.idle_in_transaction_session_timeout, 10)) + } return data } diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index 00ea76111..0d5e0376d 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -65,6 +65,7 @@ var ConnectionParameters = function (config) { this.application_name = val('application_name', config, 'PGAPPNAME') this.fallback_application_name = val('fallback_application_name', config, false) this.statement_timeout = val('statement_timeout', config, false) + this.idle_in_transaction_session_timeout = val('idle_in_transaction_session_timeout', config, false) this.query_timeout = val('query_timeout', config, false) if (config.connectionTimeoutMillis === undefined) { diff --git a/packages/pg/lib/defaults.js b/packages/pg/lib/defaults.js index bd1bf6de6..120b8c7b5 100644 --- a/packages/pg/lib/defaults.js +++ b/packages/pg/lib/defaults.js @@ -59,6 +59,10 @@ module.exports = { // false=unlimited statement_timeout: false, + // Terminate any session with an open transaction that has been idle for longer than the specified duration in milliseconds + // false=unlimited + idle_in_transaction_session_timeout: false, + // max milliseconds to wait for query to complete (client side) query_timeout: false, diff --git a/packages/pg/test/integration/client/idle_in_transaction_session_timeout-tests.js b/packages/pg/test/integration/client/idle_in_transaction_session_timeout-tests.js new file mode 100644 index 000000000..18162f545 --- /dev/null +++ b/packages/pg/test/integration/client/idle_in_transaction_session_timeout-tests.js @@ -0,0 +1,79 @@ +'use strict' +var helper = require('./test-helper') +var Client = helper.Client + +var suite = new helper.Suite() + +var conInfo = helper.config + +function getConInfo (override) { + return Object.assign({}, conInfo, override ) +} + +function testClientVersion(cb) { + var client = new Client({}) + client.connect(assert.success(function () { + helper.versionGTE(client, 100000, assert.success(function(isGreater) { + return client.end(assert.success(function () { + if (!isGreater) { + console.log('skip idle_in_transaction_session_timeout at client-level is only available in v10 and above'); + return; + } + cb(); + })) + })) + })) +} + +function getIdleTransactionSessionTimeout (conf, cb) { + var client = new Client(conf) + client.connect(assert.success(function () { + client.query('SHOW idle_in_transaction_session_timeout', assert.success(function (res) { + var timeout = res.rows[0].idle_in_transaction_session_timeout + cb(timeout) + client.end() + })) + })) +} + +if (!helper.args.native) { // idle_in_transaction_session_timeout is not supported with the native client + testClientVersion(function(){ + suite.test('No default idle_in_transaction_session_timeout ', function (done) { + getConInfo() + getIdleTransactionSessionTimeout({}, function (res) { + assert.strictEqual(res, '0') // 0 = no timeout + done() + }) + }) + + suite.test('idle_in_transaction_session_timeout integer is used', function (done) { + var conf = getConInfo({ + 'idle_in_transaction_session_timeout': 3000 + }) + getIdleTransactionSessionTimeout(conf, function (res) { + assert.strictEqual(res, '3s') + done() + }) + }) + + suite.test('idle_in_transaction_session_timeout float is used', function (done) { + var conf = getConInfo({ + 'idle_in_transaction_session_timeout': 3000.7 + }) + getIdleTransactionSessionTimeout(conf, function (res) { + assert.strictEqual(res, '3s') + done() + }) + }) + + suite.test('idle_in_transaction_session_timeout string is used', function (done) { + var conf = getConInfo({ + 'idle_in_transaction_session_timeout': '3000' + }) + getIdleTransactionSessionTimeout(conf, function (res) { + assert.strictEqual(res, '3s') + done() + }) + }) + }) +} diff --git a/packages/pg/test/unit/connection-parameters/creation-tests.js b/packages/pg/test/unit/connection-parameters/creation-tests.js index fc9f6521f..5d200be0a 100644 --- a/packages/pg/test/unit/connection-parameters/creation-tests.js +++ b/packages/pg/test/unit/connection-parameters/creation-tests.js @@ -22,7 +22,8 @@ var compare = function (actual, expected, type) { assert.equal(actual.host, expected.host, type + ' host') assert.equal(actual.password, expected.password, type + ' password') assert.equal(actual.binary, expected.binary, type + ' binary') - assert.equal(actual.statement_timout, expected.statement_timout, type + ' statement_timeout') + assert.equal(actual.statement_timeout, expected.statement_timeout, type + ' statement_timeout') + assert.equal(actual.idle_in_transaction_session_timeout, expected.idle_in_transaction_session_timeout, type + ' idle_in_transaction_session_timeout') } test('ConnectionParameters initializing from defaults', function () { @@ -38,7 +39,9 @@ test('ConnectionParameters initializing from defaults with connectionString set' port: 7777, password: 'mypassword', host: 'foo.bar.net', - binary: defaults.binary + binary: defaults.binary, + statement_timeout: false, + idle_in_transaction_session_timeout: false, } var original_value = defaults.connectionString @@ -62,7 +65,8 @@ test('ConnectionParameters initializing from config', function () { ssl: { asdf: 'blah' }, - statement_timeout: 15000 + statement_timeout: 15000, + idle_in_transaction_session_timeout: 15000 } var subject = new ConnectionParameters(config) compare(subject, config, 'config')