From cb447da7d054e658840fe9c929e697b01c185aee Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Mon, 15 Mar 2021 04:11:14 +0100 Subject: [PATCH] Added harder timeouts to http utility. Split owner and query database users. --- config/default.js | 16 ++++++++++++---- knexfile.js | 4 ++-- src/knex.js | 2 +- src/utils/http.js | 26 ++++++++++++++++++++++++-- src/web/postgraphile.js | 2 +- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/config/default.js b/config/default.js index b572d9ec..d5d2a871 100644 --- a/config/default.js +++ b/config/default.js @@ -1,9 +1,17 @@ module.exports = { database: { - host: '127.0.0.1', - user: 'user', - password: 'password', - database: 'traxxx', + owner: { + host: '127.0.0.1', + user: 'user', + password: 'password', + database: 'traxxx', + }, + query: { + host: '127.0.0.1', + user: 'user', + password: 'password', + database: 'traxxx', + }, }, web: { host: '0.0.0.0', diff --git a/knexfile.js b/knexfile.js index 8d6615e0..4e98ae17 100644 --- a/knexfile.js +++ b/knexfile.js @@ -3,6 +3,6 @@ const config = require('config'); module.exports = { - client: 'pg', - connection: config.database, + client: 'pg', + connection: config.database.owner, }; diff --git a/src/knex.js b/src/knex.js index fa79c660..0c77d14b 100644 --- a/src/knex.js +++ b/src/knex.js @@ -5,7 +5,7 @@ const knex = require('knex'); module.exports = knex({ client: 'pg', - connection: config.database, + connection: config.database.owner, // performance overhead, don't use asyncStackTraces in production asyncStackTraces: process.env.NODE_ENV === 'development', // debug: process.env.NODE_ENV === 'development', diff --git a/src/utils/http.js b/src/utils/http.js index 69ae14fa..c1439770 100644 --- a/src/utils/http.js +++ b/src/utils/http.js @@ -1,6 +1,7 @@ 'use strict'; const config = require('config'); +const Promise = require('bluebird'); const bhttp = require('bhttp'); const util = require('util'); const stream = require('stream'); @@ -15,7 +16,12 @@ const argv = require('../argv'); const pipeline = util.promisify(stream.pipeline); const limiters = {}; +Promise.config({ + cancellation: true, +}); + const defaultOptions = { + timeout: 60000, encodeJSON: true, headers: { 'user-agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1', @@ -67,6 +73,7 @@ function getLimiter(options = {}, url) { limiters[interval][concurrency] = new Bottleneck({ minTime: interval, maxConcurrent: concurrency, + timeout: (options.timeout || defaultOptions.timeout) + 10000, // timeout 10 seconds after bhttp should }); } @@ -83,7 +90,7 @@ async function request(method = 'get', url, body, requestOptions = {}, limiter) ...defaultOptions.headers, ...requestOptions.headers, }, - responseTimeout: requestOptions.responseTimeout || requestOptions.timeout || 60000, + responseTimeout: requestOptions.responseTimeout || requestOptions.timeout || defaultOptions.timeout, stream: !!requestOptions.destination, session: null, }; @@ -131,10 +138,25 @@ async function request(method = 'get', url, body, requestOptions = {}, limiter) }; } +function getTimeout(options, url) { + return new Promise((resolve, reject, onCancel) => { + const timeoutId = setTimeout(() => { + reject(new Error(`URL ${url} timed out`)); + }, (options.timeout || defaultOptions.timeout) + 10000); + + onCancel(() => clearTimeout(timeoutId)); + }); +} + async function scheduleRequest(method = 'get', url, body, options) { const limiter = getLimiter(options, url); + const timeout = getTimeout(options, url); - return limiter.schedule(() => request(method, url, body, options, limiter)); + const result = await limiter.schedule(() => Promise.race([request(method, url, body, options, limiter), timeout])); + + timeout.cancel(); + + return result; } async function get(url, options) { diff --git a/src/web/postgraphile.js b/src/web/postgraphile.js index 7bc3364a..d7158916 100644 --- a/src/web/postgraphile.js +++ b/src/web/postgraphile.js @@ -10,7 +10,7 @@ const PgOrderByRelatedPlugin = require('@graphile-contrib/pg-order-by-related'); const { ActorPlugins, SitePlugins, ReleasePlugins } = require('./plugins/plugins'); -const connectionString = `postgres://${config.database.user}:${config.database.password}@${config.database.host}:5432/${config.database.database}`; +const connectionString = `postgres://${config.database.query.user}:${config.database.query.password}@${config.database.query.host}:5432/${config.database.query.database}`; module.exports = postgraphile( connectionString,