Reduce sql-api communication timeout, and allow overriding it

Introduces new sqlapi.timeout directive, defaults to 100 ms
Includes testcase.
Closes #167
This commit is contained in:
Sandro Santilli 2014-02-27 10:26:42 +01:00
parent cf01f01bc9
commit f284362988
8 changed files with 65 additions and 5 deletions

View File

@ -8,6 +8,8 @@ Enhancements:
- Improve speed of instanciating a map (#147, #159, #165)
- Give meaningful error on attempts to use map tokens
with attribute service (#156)
- Reduce sql-api communication timeout, and allow overriding (#167)
[ new sqlapi.timeout directive, defaults to 100 ms ]
1.8.2 -- 2014-02-25
-------------------

View File

@ -106,7 +106,10 @@ var config = {
// Maximum lenght of SQL query for GET
// requests. Longer queries will be sent
// using POST. Defaults to 2048
max_get_sql_length: 2048
max_get_sql_length: 2048,
// Maximum time to wait for a response,
// in milliseconds. Defaults to 100.
timeout: 100
}
,varnish: {
host: 'localhost',

View File

@ -100,7 +100,10 @@ var config = {
// Maximum lenght of SQL query for GET
// requests. Longer queries will be sent
// using POST. Defaults to 2048
max_get_sql_length: 2048
max_get_sql_length: 2048,
// Maximum time to wait for a response,
// in milliseconds. Defaults to 100.
timeout: 100
}
,varnish: {
host: 'localhost',

View File

@ -100,7 +100,10 @@ var config = {
// Maximum lenght of SQL query for GET
// requests. Longer queries will be sent
// using POST. Defaults to 2048
max_get_sql_length: 2048
max_get_sql_length: 2048,
// Maximum time to wait for a response,
// in milliseconds. Defaults to 100.
timeout: 100
}
,varnish: {
host: 'localhost',

View File

@ -102,7 +102,10 @@ var config = {
// Maximum lenght of SQL query for GET
// requests. Longer queries will be sent
// using POST. Defaults to 2048
max_get_sql_length: 2048
max_get_sql_length: 2048,
// Maximum time to wait for a response,
// in milliseconds. Defaults to 100.
timeout: 100
}
,varnish: {
host: '',

View File

@ -116,13 +116,15 @@ module.exports = function(){
//
var maxSockets = global.environment.maxConnections || 128;
var maxGetLen = api.max_get_sql_length || 2048;
var maxSQLTime = api.timeout || 100; // 1/10 of a second by default
var reqSpec = {
url:sqlapi,
json:true,
headers:{host: sqlapihostname}
// http://nodejs.org/api/http.html#http_agent_maxsockets
,pool:{maxSockets:maxSockets}
//,timeout:100
// timeout in milliseconds
,timeout:maxSQLTime
}
if ( sql.length > maxGetLen ) {
reqSpec.method = 'POST';

View File

@ -1128,6 +1128,47 @@ suite('multilayer', function() {
);
});
// See https://github.com/CartoDB/Windshaft-cartodb/issues/167
test("lack of response from sql-api will result in a timeout", function(done) {
var layergroup = {
version: '1.0.0',
layers: [
{ options: {
sql: "select *, 'SQLAPINOANSWER' from test_table",
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
cartocss_version: '2.1.0'
} }
]
};
Step(
function do_post()
{
var next = this;
assert.response(server, {
url: '/tiles/layergroup',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res, err) { next(err, res); });
},
function check_post(err, res) {
if ( err ) throw err;
assert.equal(res.statusCode, 400, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.errors, 'Missing "errors" in response: ' + JSON.stringify(parsed));
assert.equal(parsed.errors.length, 1);
var msg = parsed.errors[0];
assert.equal(msg, 'Error: could not fetch source tables: ETIMEDOUT');
return null;
},
function finish(err) {
done(err);
}
);
});
suiteTeardown(function(done) {

View File

@ -42,6 +42,9 @@ o.prototype.handleQuery = function(query, res) {
if ( query.q.match('SQLAPIERROR') ) {
res.statusCode = 400;
res.write(JSON.stringify({'error':'Some error occurred'}));
} else if ( query.q.match('SQLAPINOANSWER') ) {
console.log("SQLAPIEmulator will never respond, on request");
return;
} else if ( query.q.match('EPOCH.* as max') ) {
// This is the structure of the known query sent by tiler
var row = {