2015-12-09 07:02:08 +08:00
|
|
|
'use strict';
|
|
|
|
|
2015-12-22 02:57:10 +08:00
|
|
|
var JobRunner = require('./job_runner');
|
2015-12-16 22:57:58 +08:00
|
|
|
var JobQueuePool = require('./job_queue_pool');
|
|
|
|
var JobQueueConsumer = require('./job_queue_consumer');
|
|
|
|
var JobSubscriber = require('./job_subscriber');
|
|
|
|
var UserDatabaseMetadataService = require('./user_database_metadata_service');
|
2015-12-22 02:57:10 +08:00
|
|
|
var EventEmitter = require('events').EventEmitter;
|
2015-12-23 03:12:10 +08:00
|
|
|
var util = require('util');
|
2015-12-09 07:02:08 +08:00
|
|
|
|
2015-12-23 03:12:10 +08:00
|
|
|
function Batch(metadataBackend) {
|
|
|
|
EventEmitter.call(this);
|
|
|
|
this.metadataBackend = metadataBackend;
|
|
|
|
this.jobSubscriber = new JobSubscriber();
|
|
|
|
this.userDatabaseMetadataService = new UserDatabaseMetadataService(this.metadataBackend);
|
|
|
|
this.jobRunner = new JobRunner(this.metadataBackend, this.userDatabaseMetadataService);
|
|
|
|
}
|
|
|
|
util.inherits(Batch, EventEmitter);
|
|
|
|
|
|
|
|
Batch.prototype.start = function () {
|
|
|
|
var self = this;
|
|
|
|
this.jobQueuePool = new JobQueuePool();
|
2015-12-09 07:02:08 +08:00
|
|
|
|
2015-12-22 02:57:10 +08:00
|
|
|
// subscribe to message exchange broker in order to know what queues are available
|
2015-12-23 03:12:10 +08:00
|
|
|
this.jobSubscriber.subscribe(function onMessage(channel, host) {
|
|
|
|
var jobQueueConsumer = self.jobQueuePool.get(host);
|
2015-12-16 22:57:58 +08:00
|
|
|
|
2015-12-22 02:57:10 +08:00
|
|
|
// if queue consumer is not registered yet
|
2015-12-16 22:57:58 +08:00
|
|
|
if (!jobQueueConsumer) {
|
|
|
|
|
|
|
|
// creates new one
|
2015-12-23 03:12:10 +08:00
|
|
|
jobQueueConsumer = new JobQueueConsumer(self.metadataBackend, host);
|
2015-12-16 22:57:58 +08:00
|
|
|
|
|
|
|
// register it in batch service
|
2015-12-23 03:12:10 +08:00
|
|
|
self.jobQueuePool.add(host, jobQueueConsumer);
|
2015-12-16 22:57:58 +08:00
|
|
|
|
|
|
|
// while read from queue then perform job
|
2015-12-22 02:57:10 +08:00
|
|
|
jobQueueConsumer.on('data', function (jobId) {
|
2015-12-16 22:57:58 +08:00
|
|
|
|
|
|
|
// limit one job at the same time per queue (queue <1:1> db intance)
|
|
|
|
jobQueueConsumer.pause();
|
|
|
|
|
2015-12-23 03:12:10 +08:00
|
|
|
var job = self.jobRunner.run(jobId);
|
2015-12-16 22:57:58 +08:00
|
|
|
|
2015-12-22 02:57:10 +08:00
|
|
|
job.on('done', function () {
|
2015-12-16 22:57:58 +08:00
|
|
|
// next job
|
2015-12-23 03:12:10 +08:00
|
|
|
self.emit('job:done', jobId);
|
2015-12-16 22:57:58 +08:00
|
|
|
jobQueueConsumer.resume();
|
|
|
|
});
|
2015-12-22 02:57:10 +08:00
|
|
|
|
|
|
|
job.on('error', function (err) {
|
|
|
|
console.error(err.stack || err);
|
2015-12-23 03:12:10 +08:00
|
|
|
self.emit('job:failed', jobId);
|
2015-12-22 02:57:10 +08:00
|
|
|
jobQueueConsumer.resume();
|
|
|
|
});
|
|
|
|
|
2015-12-16 22:57:58 +08:00
|
|
|
})
|
|
|
|
.on('error', function (err) {
|
|
|
|
console.error(err.stack || err);
|
2015-12-23 03:12:10 +08:00
|
|
|
self.jobQueuePool.remove(host);
|
|
|
|
})
|
|
|
|
.on('end', function () {
|
|
|
|
self.jobQueuePool.remove(host);
|
2015-12-16 22:57:58 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2015-12-23 03:12:10 +08:00
|
|
|
};
|
2015-12-17 01:13:48 +08:00
|
|
|
|
2015-12-23 03:12:10 +08:00
|
|
|
Batch.prototype.stop = function () {
|
|
|
|
this.jobSubscriber.unsubscribe();
|
2015-12-09 07:02:08 +08:00
|
|
|
};
|
2015-12-23 03:12:10 +08:00
|
|
|
|
|
|
|
module.exports = Batch;
|