Skip to content

Commit 16e9e70

Browse files
committed
Cancel with user statement_timeout limit from redis
1 parent 26e4cb3 commit 16e9e70

File tree

4 files changed

+68
-5
lines changed

4 files changed

+68
-5
lines changed

batch/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module.exports = function batchFactory (metadataBackend, redisPool, name, statsd
2323
var queryRunner = new QueryRunner(userDatabaseMetadataService);
2424
var jobCanceller = new JobCanceller(userDatabaseMetadataService);
2525
var jobService = new JobService(jobBackend, jobCanceller);
26-
var jobRunner = new JobRunner(jobService, jobQueue, queryRunner, statsdClient);
26+
var jobRunner = new JobRunner(jobService, jobQueue, queryRunner, metadataBackend, statsdClient);
2727
var logger = new BatchLogger(loggerPath);
2828

2929
return new Batch(

batch/job_runner.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ var jobStatus = require('./job_status');
55
var Profiler = require('step-profiler');
66
var _ = require('underscore');
77

8-
function JobRunner(jobService, jobQueue, queryRunner, statsdClient) {
8+
var REDIS_LIMITS = {
9+
DB: 5,
10+
PREFIX: 'limits:batch:' // + username
11+
};
12+
13+
function JobRunner(jobService, jobQueue, queryRunner, metadataBackend, statsdClient) {
914
this.jobService = jobService;
1015
this.jobQueue = jobQueue;
1116
this.queryRunner = queryRunner;
17+
this.metadataBackend = metadataBackend;
1218
this.statsdClient = statsdClient;
1319
}
1420

@@ -62,7 +68,14 @@ JobRunner.prototype.getQueryStatementTimeout = function(username, callback) {
6268
timeout = global.settings.batch_query_timeout;
6369
}
6470

65-
return callback(null, timeout);
71+
var batchLimitsKey = REDIS_LIMITS.PREFIX + username;
72+
this.metadataBackend.redisCmd(REDIS_LIMITS.DB, 'HGET', [batchLimitsKey, 'timeout'], function(err, timeoutLimit) {
73+
if (timeoutLimit !== null && Number.isFinite(+timeoutLimit)) {
74+
timeout = +timeoutLimit;
75+
}
76+
77+
return callback(null, timeout);
78+
});
6679
};
6780

6881
JobRunner.prototype._run = function (job, query, timeout, profiler, callback) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require('../../helper');
2+
3+
var assert = require('../../support/assert');
4+
var BatchTestClient = require('../../support/batch-test-client');
5+
var JobStatus = require('../../../batch/job_status');
6+
var redisUtils = require('../../support/redis_utils');
7+
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
8+
9+
describe('batch query statement_timeout limit', function() {
10+
11+
before(function(done) {
12+
this.batchTestClient = new BatchTestClient();
13+
this.batchQueryTimeout = global.settings.batch_query_timeout;
14+
global.settings.batch_query_timeout = 15000;
15+
metadataBackend.redisCmd(5, 'HMSET', ['limits:batch:vizzuality', 'timeout', 100], done);
16+
});
17+
18+
after(function(done) {
19+
global.settings.batch_query_timeout = this.batchQueryTimeout;
20+
redisUtils.clean('limits:batch:*', function() {
21+
this.batchTestClient.drain(done);
22+
}.bind(this));
23+
});
24+
25+
function jobPayload(query) {
26+
return {
27+
query: query
28+
};
29+
}
30+
31+
it('should cancel with user statement_timeout limit', function (done) {
32+
var payload = jobPayload('select pg_sleep(10)');
33+
this.batchTestClient.createJob(payload, function(err, jobResult) {
34+
if (err) {
35+
return done(err);
36+
}
37+
jobResult.getStatus(function (err, job) {
38+
if (err) {
39+
return done(err);
40+
}
41+
assert.equal(job.status, JobStatus.FAILED);
42+
assert.ok(job.failed_reason.match(/statement.*timeout/));
43+
return done();
44+
});
45+
});
46+
});
47+
48+
});

test/integration/batch/job_runner.test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ var JOB = {
3939
};
4040

4141
describe('job runner', function() {
42-
var jobRunner = new JobRunner(jobService, jobQueue, queryRunner, statsdClient);
42+
var jobRunner = new JobRunner(jobService, jobQueue, queryRunner, metadataBackend, statsdClient);
4343

4444
after(function (done) {
45-
redisUtils.clean('batch:*', done);
45+
redisUtils.clean('batch:*', function() {
46+
redisUtils.clean('limits:batch:*', done);
47+
});
4648
});
4749

4850
it('.run() should run a job', function (done) {

0 commit comments

Comments
 (0)