tor-router/src/TorPool.js

85 lines
2.2 KiB
JavaScript
Raw Normal View History

2017-01-31 15:56:42 +00:00
/* From http://stackoverflow.com/questions/1985260/javascript-array-rotate */
Array.prototype.rotate = (function() {
// save references to array functions to make lookup faster
var push = Array.prototype.push,
splice = Array.prototype.splice;
return function(count) {
var len = this.length >>> 0, // convert to uint
count = count >> 0; // convert to int
// convert count to value in range [0, len)
count = ((count % len) + len) % len;
// use splice.call() instead of this.splice() to make function generic
push.apply(this, splice.call(this, 0, count));
return this;
};
})();
const EventEmitter = require('eventemitter2').EventEmitter2;
const async = require('async');
const TorProcess = require('./TorProcess');
const temp = require('temp');
const _ = require('lodash');
temp.track();
class TorPool extends EventEmitter {
2017-01-31 23:11:36 +00:00
constructor(tor_path, config, logger) {
2017-01-31 15:56:42 +00:00
super();
config = config || {};
this.tor_config = config;
this.tor_path = tor_path || 'tor';
this._instances = [];
2017-01-31 23:11:36 +00:00
this.logger = logger;
2017-01-31 15:56:42 +00:00
}
get instances() { return this._instances.filter((tor) => tor.ready).slice(0); }
2017-01-31 15:56:42 +00:00
create_instance(callback) {
let config = _.extend({}, this.tor_config)
2017-01-31 23:11:36 +00:00
let instance = new TorProcess(this.tor_path, config, this.logger);
2017-01-31 15:56:42 +00:00
instance.create((error) => {
if (error) return callback(error);
this._instances.push(instance);
2017-03-22 17:08:50 +00:00
2017-01-31 15:56:42 +00:00
instance.once('error', callback)
instance.once('ready', () => {
this.emit('instance_created', instance);
2017-01-31 23:11:36 +00:00
callback && callback(null, instance);
2017-01-31 15:56:42 +00:00
});
});
}
create(instances, callback) {
if (!Number(instances)) return callback(null, []);
async.map(Array.from(Array(Number(instances))), (nothing, next) => {
this.create_instance(next);
2017-01-31 23:11:36 +00:00
}, (callback || (() => {})));
2017-01-31 15:56:42 +00:00
}
remove(instances, callback) {
let instances_to_remove = this._instances.splice(0, instances);
async.each(instances_to_remove, (instance, next) => {
instance.exit(next);
}, callback);
}
2017-01-31 15:56:42 +00:00
next() {
2017-01-31 23:11:36 +00:00
this._instances = this._instances.rotate(1);
2017-01-31 15:56:42 +00:00
return this.instances[0];
}
exit() {
this.instances.forEach((tor) => tor.exit());
}
new_ips() {
this.instances.forEach((tor) => tor.new_ip());
}
};
module.exports = TorPool;