2015-12-22 02:57:10 +08:00
|
|
|
'use strict';
|
|
|
|
|
2016-01-23 01:22:21 +08:00
|
|
|
var errorCodes = require('../app/postgresql/error_codes').codeToCondition;
|
2016-04-06 00:50:04 +08:00
|
|
|
var jobStatus = require('./job_status');
|
2015-12-22 02:57:10 +08:00
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
function getNextQuery(job) {
|
|
|
|
if (!Array.isArray(job.query)) {
|
|
|
|
return {
|
|
|
|
query: job.query
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < job.query.length; i++) {
|
2016-04-06 00:50:04 +08:00
|
|
|
if (job.query[i].status === jobStatus.PENDING) {
|
2016-03-31 18:39:03 +08:00
|
|
|
return {
|
|
|
|
index: i,
|
|
|
|
query: job.query[i].query
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function isLastQuery(job, index) {
|
|
|
|
if (!Array.isArray(job.query)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index >= (job.query.length -1)) {
|
|
|
|
return true;
|
|
|
|
}
|
2016-01-22 19:43:41 +08:00
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function JobRunner(jobBackend, jobQueue, queryRunner,userDatabaseMetadataService) {
|
2016-01-08 22:47:59 +08:00
|
|
|
this.jobBackend = jobBackend;
|
2016-03-31 18:39:03 +08:00
|
|
|
this.jobQueue = jobQueue;
|
|
|
|
this.queryRunner = queryRunner;
|
2015-12-22 02:57:10 +08:00
|
|
|
this.userDatabaseMetadataService = userDatabaseMetadataService;
|
|
|
|
}
|
|
|
|
|
2016-01-08 22:47:59 +08:00
|
|
|
JobRunner.prototype.run = function (job_id, callback) {
|
2015-12-22 02:57:10 +08:00
|
|
|
var self = this;
|
2016-01-08 18:32:01 +08:00
|
|
|
|
2016-01-08 22:47:59 +08:00
|
|
|
self.jobBackend.get(job_id, function (err, job) {
|
2015-12-22 02:57:10 +08:00
|
|
|
if (err) {
|
2016-01-08 22:47:59 +08:00
|
|
|
return callback(err);
|
2015-12-22 02:57:10 +08:00
|
|
|
}
|
2015-12-29 17:19:10 +08:00
|
|
|
|
2016-04-06 00:50:04 +08:00
|
|
|
if (job.status !== jobStatus.PENDING) {
|
2016-03-31 18:39:03 +08:00
|
|
|
var invalidJobStatusError = new Error([
|
|
|
|
'Cannot run job',
|
|
|
|
job.job_id,
|
|
|
|
'due to its status is',
|
|
|
|
job.status
|
|
|
|
].join(' '));
|
|
|
|
invalidJobStatusError.name = 'InvalidJobStatus';
|
|
|
|
return callback(invalidJobStatusError);
|
2015-12-31 03:16:18 +08:00
|
|
|
}
|
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
var query = getNextQuery(job);
|
|
|
|
|
|
|
|
if (!query) {
|
|
|
|
var queryNotFoundError = new Error([
|
|
|
|
'Cannot run job',
|
|
|
|
job.job_id,
|
|
|
|
', there is no query to run'
|
|
|
|
].join(' '));
|
|
|
|
queryNotFoundError.name = 'QueryNotFound';
|
|
|
|
return callback(queryNotFoundError);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.jobBackend.setRunning(job, query.index, function (err, job) {
|
2015-12-22 02:57:10 +08:00
|
|
|
if (err) {
|
2016-01-08 22:47:59 +08:00
|
|
|
return callback(err);
|
2015-12-22 02:57:10 +08:00
|
|
|
}
|
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
self._run(job, query, callback);
|
2016-01-08 22:47:59 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
2015-12-22 02:57:10 +08:00
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
JobRunner.prototype._run = function (job, query, callback) {
|
2016-03-18 23:05:36 +08:00
|
|
|
var self = this;
|
2016-03-31 18:39:03 +08:00
|
|
|
self.userDatabaseMetadataService.getUserMetadata(job.user, function (err, userDatabaseMetadata) {
|
2016-03-18 21:57:18 +08:00
|
|
|
if (err) {
|
2016-03-31 18:39:03 +08:00
|
|
|
return callback(err);
|
2016-03-18 21:57:18 +08:00
|
|
|
}
|
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
self.queryRunner.run(job.job_id, query.query, userDatabaseMetadata, function (err /*, result */) {
|
|
|
|
if (err) {
|
|
|
|
// if query has been cancelled then it's going to get the current
|
|
|
|
// job status saved by query_canceller
|
|
|
|
if (errorCodes[err.code.toString()] === 'query_canceled') {
|
|
|
|
return self.jobBackend.get(job.job_id, callback);
|
|
|
|
}
|
2016-03-21 22:10:05 +08:00
|
|
|
|
2016-03-31 19:36:58 +08:00
|
|
|
return self.jobBackend.setFailed(job, err, query.index, callback);
|
2016-03-21 22:10:05 +08:00
|
|
|
}
|
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
if (isLastQuery(job, query.index)) {
|
|
|
|
return self.jobBackend.setDone(job, query.index, callback);
|
2016-03-21 22:10:05 +08:00
|
|
|
}
|
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
self.jobBackend.setJobPendingAndQueryDone(job, query.index, function (err, job) {
|
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
2015-12-31 22:42:31 +08:00
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
self.jobQueue.enqueue(job.job_id, userDatabaseMetadata.host, function (err){
|
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
2016-01-08 22:47:59 +08:00
|
|
|
|
2016-03-31 18:39:03 +08:00
|
|
|
callback(null, job);
|
|
|
|
});
|
2015-12-22 02:57:10 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = JobRunner;
|