2015-12-31 03:16:18 +08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var PSQL = require('cartodb-psql');
|
|
|
|
|
2019-12-24 01:19:08 +08:00
|
|
|
function JobCanceller () {
|
2015-12-31 03:16:18 +08:00
|
|
|
}
|
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
module.exports = JobCanceller;
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
JobCanceller.prototype.cancel = function (job, callback) {
|
2018-05-30 23:36:55 +08:00
|
|
|
const dbConfiguration = {
|
|
|
|
host: job.data.host,
|
|
|
|
port: job.data.port,
|
|
|
|
dbname: job.data.dbname,
|
|
|
|
user: job.data.dbuser,
|
2019-12-24 01:19:08 +08:00
|
|
|
pass: job.data.pass
|
2018-05-30 23:36:55 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
doCancel(job.data.job_id, dbConfiguration, callback);
|
2016-05-14 00:50:55 +08:00
|
|
|
};
|
|
|
|
|
2019-12-27 01:28:01 +08:00
|
|
|
function doCancel (jobId, dbConfiguration, callback) {
|
2018-06-05 23:56:29 +08:00
|
|
|
var pg = new PSQL(dbConfiguration);
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2019-12-27 01:28:01 +08:00
|
|
|
getQueryPID(pg, jobId, function (err, pid) {
|
2016-05-14 00:50:55 +08:00
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
2015-12-31 03:16:18 +08:00
|
|
|
}
|
|
|
|
|
2016-05-23 16:26:09 +08:00
|
|
|
if (!pid) {
|
|
|
|
return callback();
|
|
|
|
}
|
|
|
|
|
2016-05-16 07:22:47 +08:00
|
|
|
doCancelQuery(pg, pid, function (err, isCancelled) {
|
2015-12-31 03:16:18 +08:00
|
|
|
if (err) {
|
2016-01-08 22:47:59 +08:00
|
|
|
return callback(err);
|
2015-12-31 03:16:18 +08:00
|
|
|
}
|
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
if (!isCancelled) {
|
|
|
|
return callback(new Error('Query has not been cancelled'));
|
|
|
|
}
|
2016-03-31 21:11:35 +08:00
|
|
|
|
2016-05-23 16:26:09 +08:00
|
|
|
callback();
|
2016-01-08 22:47:59 +08:00
|
|
|
});
|
|
|
|
});
|
2016-05-14 00:50:55 +08:00
|
|
|
}
|
2016-01-13 23:25:25 +08:00
|
|
|
|
2019-12-27 01:28:01 +08:00
|
|
|
function getQueryPID (pg, jobId, callback) {
|
|
|
|
var getPIDQuery = "SELECT pid FROM pg_stat_activity WHERE query LIKE '/* " + jobId + " */%'";
|
2016-01-08 22:47:59 +08:00
|
|
|
|
2019-12-24 01:19:08 +08:00
|
|
|
pg.query(getPIDQuery, function (err, result) {
|
2016-01-23 01:22:21 +08:00
|
|
|
if (err) {
|
2016-01-08 22:47:59 +08:00
|
|
|
return callback(err);
|
|
|
|
}
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2016-01-08 22:47:59 +08:00
|
|
|
if (!result.rows[0] || !result.rows[0].pid) {
|
2016-05-23 16:26:09 +08:00
|
|
|
// query is not running actually, but we have to callback w/o error to cancel the job anyway.
|
|
|
|
return callback();
|
2016-01-08 22:47:59 +08:00
|
|
|
}
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
callback(null, result.rows[0].pid);
|
|
|
|
});
|
|
|
|
}
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2019-12-24 01:19:08 +08:00
|
|
|
function doCancelQuery (pg, pid, callback) {
|
2016-05-14 00:50:55 +08:00
|
|
|
var cancelQuery = 'SELECT pg_cancel_backend(' + pid + ')';
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
pg.query(cancelQuery, function (err, result) {
|
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
var isCancelled = result.rows[0].pg_cancel_backend;
|
2015-12-31 03:16:18 +08:00
|
|
|
|
2016-05-14 00:50:55 +08:00
|
|
|
callback(null, isCancelled);
|
2015-12-31 03:16:18 +08:00
|
|
|
});
|
2016-05-14 00:50:55 +08:00
|
|
|
}
|