CartoDB-SQL-API/batch/job_canceller.js

79 lines
1.8 KiB
JavaScript
Raw Normal View History

'use strict';
var PSQL = require('cartodb-psql');
function JobCanceller() {
}
2016-05-14 00:50:55 +08:00
module.exports = JobCanceller;
2016-05-14 00:50:55 +08:00
JobCanceller.prototype.cancel = function (job, callback) {
const dbConfiguration = {
host: job.data.host,
port: job.data.port,
dbname: job.data.dbname,
user: job.data.dbuser,
pass: job.data.pass,
};
doCancel(job.data.job_id, dbConfiguration, callback);
2016-05-14 00:50:55 +08:00
};
function doCancel(job_id, dbConfiguration, callback) {
var pg = new PSQL(dbConfiguration);
2016-05-14 00:50:55 +08:00
getQueryPID(pg, job_id, function (err, pid) {
if (err) {
return callback(err);
}
if (!pid) {
return callback();
}
2016-05-16 07:22:47 +08:00
doCancelQuery(pg, pid, function (err, isCancelled) {
if (err) {
return callback(err);
}
2016-05-14 00:50:55 +08:00
if (!isCancelled) {
return callback(new Error('Query has not been cancelled'));
}
callback();
});
});
2016-05-14 00:50:55 +08:00
}
2016-05-14 00:50:55 +08:00
function getQueryPID(pg, job_id, callback) {
var getPIDQuery = "SELECT pid FROM pg_stat_activity WHERE query LIKE '/* " + job_id + " */%'";
pg.query(getPIDQuery, function(err, result) {
if (err) {
return callback(err);
}
if (!result.rows[0] || !result.rows[0].pid) {
// query is not running actually, but we have to callback w/o error to cancel the job anyway.
return callback();
}
2016-05-14 00:50:55 +08:00
callback(null, result.rows[0].pid);
});
}
2016-05-16 07:22:47 +08:00
function doCancelQuery(pg, pid, callback) {
2016-05-14 00:50:55 +08:00
var cancelQuery = 'SELECT pg_cancel_backend(' + pid + ')';
2016-05-14 00:50:55 +08:00
pg.query(cancelQuery, function (err, result) {
if (err) {
return callback(err);
}
2016-05-14 00:50:55 +08:00
var isCancelled = result.rows[0].pg_cancel_backend;
2016-05-14 00:50:55 +08:00
callback(null, isCancelled);
});
2016-05-14 00:50:55 +08:00
}