From 01a71ee60e01f693a9dac15b5e6c96b076767571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa=20Aubert?= Date: Wed, 9 Aug 2017 12:50:16 +0200 Subject: [PATCH] Apply user timeout to ogr2ogr command --- app/controllers/query_controller.js | 7 +++++-- app/models/formats/ogr.js | 19 +++++++++++++++++++ app/services/user_database_service.js | 27 +++++++++++++++++++++++---- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/app/controllers/query_controller.js b/app/controllers/query_controller.js index c287d2ed..302cebf5 100644 --- a/app/controllers/query_controller.js +++ b/app/controllers/query_controller.js @@ -50,6 +50,7 @@ QueryController.prototype.handleQuery = function (req, res) { var skipfields; var dp = params.dp; // decimal point digits (defaults to 6) var gn = "the_geom"; // TODO: read from configuration file + var userLimits; if ( req.profiler ) { req.profiler.start('sqlapi.query'); @@ -122,12 +123,13 @@ QueryController.prototype.handleQuery = function (req, res) { function getUserDBInfo() { self.userDatabaseService.getConnectionParams(new AuthApi(req, params), cdbUsername, this); }, - function queryExplain(err, dbParams, authDbParams) { + function queryExplain(err, dbParams, authDbParams, userTimeoutLimits) { assert.ifError(err); var next = this; dbopts = dbParams; + userLimits = userTimeoutLimits; if ( req.profiler ) { req.profiler.done('setDBAuth'); @@ -217,7 +219,8 @@ QueryController.prototype.handleQuery = function (req, res) { filename: filename, bufferedRows: global.settings.bufferedRows, callback: params.callback, - abortChecker: checkAborted + abortChecker: checkAborted, + timeout: userLimits.timeout }; if ( req.profiler ) { diff --git a/app/models/formats/ogr.js b/app/models/formats/ogr.js index 38cdb948..42f1b4f0 100644 --- a/app/models/formats/ogr.js +++ b/app/models/formats/ogr.js @@ -65,6 +65,8 @@ OgrFormat.prototype.toOGR = function(options, out_format, out_filename, callback var dbpass = dbopts.pass; var dbname = dbopts.dbname; + var timeout = options.timeout; + var that = this; var columns = []; @@ -167,9 +169,20 @@ OgrFormat.prototype.toOGR = function(options, out_format, out_filename, callback ogrargs.push('-nln', out_layername); + // TODO: research if exec var child = spawn(ogr2ogr, ogrargs); + var timeouted = false; + var ogrTimeout; + if (timeout > 0) { + ogrTimeout = setTimeout(function () { + timeouted = true; + child.kill(); + }, timeout); + } + child.on('error', function (err) { + clearTimeout(ogrTimeout); next(err); }); @@ -180,6 +193,12 @@ OgrFormat.prototype.toOGR = function(options, out_format, out_filename, callback }); child.on('exit', function(code) { + clearTimeout(ogrTimeout); + + if (timeouted) { + return next(new Error('You are over platform\'s limits. Please contact us to know more details')); + } + if (code !== 0) { var errMessage = 'ogr2ogr command return code ' + code; if (stderrData.length > 0) { diff --git a/app/services/user_database_service.js b/app/services/user_database_service.js index 60ebee67..f713a71c 100644 --- a/app/services/user_database_service.js +++ b/app/services/user_database_service.js @@ -54,7 +54,26 @@ UserDatabaseService.prototype.getConnectionParams = function (authApi, cdbUserna apiKey: dbParams.apikey }, next); }, - function setDBAuth(err, isAuthenticated) { + function getUserLimits (err, isAuthenticated) { + var next = this; + + if (err) { + return next(err); + } + + self.metadataBackend.getUserTimeoutRenderLimits(cdbUsername, function (err, timeoutRenderLimit) { + if (err) { + return next(err); + } + + var userLimits = { + timeout: isAuthenticated ? timeoutRenderLimit.render : timeoutRenderLimit.renderPublic + }; + + next(null, isAuthenticated, userLimits); + }); + }, + function setDBAuth(err, isAuthenticated, userLimits) { if (err) { throw err; } @@ -76,14 +95,14 @@ UserDatabaseService.prototype.getConnectionParams = function (authApi, cdbUserna var authDbOpts = _.defaults({user: user, pass: pass}, dbopts); - return this(null, dbopts, authDbOpts); + return this(null, dbopts, authDbOpts, userLimits); }, - function errorHandle(err, dbopts, authDbOpts) { + function errorHandle(err, dbopts, authDbOpts, userLimits) { if (err) { return callback(err); } - callback(null, dbopts, authDbOpts); + callback(null, dbopts, authDbOpts, userLimits); } );