Adds a sepreate file for a silent winston logger to be used whenever a logger is not specified. Replaces all callbacks with Promises in TorPool.

This commit is contained in:
Zachary Boyd 2018-09-09 00:25:40 -04:00
parent 72aa9193d2
commit c1515969b4
6 changed files with 363 additions and 439 deletions

View file

@ -5,6 +5,9 @@
### Changes ### Changes
- All methods now return promises instead of accepting callbacks. Methods now take advantage of async/await resulting in clearer code. Compatibility with node < v8 will be broken. - All methods now return promises instead of accepting callbacks. Methods now take advantage of async/await resulting in clearer code. Compatibility with node < v8 will be broken.
### Removes
- The `new_ips` and `new_ip_at` TorPool and `new_ip` TorProcess have been removed. Use `new_identites`, `new_identity_at` and `new_identity` instead.
## [3.4.3] - 2018-08-10 ## [3.4.3] - 2018-08-10
### Added ### Added

582
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -26,24 +26,6 @@ const nanoid = require('nanoid');
const fs = require('fs'); const fs = require('fs');
const WeightedList = require('js-weighted-list'); const WeightedList = require('js-weighted-list');
const load_balance_methods = {
round_robin: function (instances) {
return instances.rotate(1);
},
weighted: function (instances) {
if (!instances._weighted_list) {
instances._weighted_list = new WeightedList(
instances.map((instance) => {
return [ instance.id, instance.definition.Weight, instance ]
})
);
};
let i = instances._weighted_list.peek(instances.length).map((element) => element.data);
i._weighted_list = instances._weighted_list;
return i;
}
};
class TorPool extends EventEmitter { class TorPool extends EventEmitter {
constructor(tor_path, default_config, data_directory, load_balance_method, granax_options, logger) { constructor(tor_path, default_config, data_directory, load_balance_method, granax_options, logger) {
super(); super();
@ -54,42 +36,65 @@ class TorPool extends EventEmitter {
this.load_balance_method = load_balance_method; this.load_balance_method = load_balance_method;
!fs.existsSync(this.data_directory) && fs.mkdirSync(this.data_directory); !fs.existsSync(this.data_directory) && fs.mkdirSync(this.data_directory);
this.tor_path = tor_path; this.tor_path = tor_path;
this.logger = logger; this.logger = logger || require('./winston-silent-logger');
this.granax_options = granax_options; this.granax_options = granax_options;
} }
static get load_balance_methods() {
return {
round_robin: function (instances) {
return instances.rotate(1);
},
weighted: function (instances) {
if (!instances._weighted_list) {
instances._weighted_list = new WeightedList(
instances.map((instance) => {
return [ instance.id, instance.definition.Weight, instance ]
})
);
};
let i = instances._weighted_list.peek(instances.length).map((element) => element.data);
i._weighted_list = instances._weighted_list;
return i;
}
};
}
get instances() { get instances() {
return this._instances.slice(0).filter((tor) => tor.ready); return this._instances.slice(0).filter((tor) => tor.ready);
} }
create_instance(instance_definition, callback) { async create_instance(instance_definition) {
this._instances._weighted_list = void(0); this._instances._weighted_list = void(0);
if (!instance_definition.Config) if (!instance_definition.Config)
instance_definition.Config = _.extend({}, this.default_tor_config); instance_definition.Config = _.extend({}, this.default_tor_config);
let instance_id = nanoid(); let instance_id = nanoid();
instance_definition.Config.DataDirectory = instance_definition.Config.DataDirectory || path.join(this.data_directory, (instance_definition.Name || instance_id)); instance_definition.Config.DataDirectory = instance_definition.Config.DataDirectory || path.join(this.data_directory, (instance_definition.Name || instance_id));
let instance = new TorProcess(this.tor_path, instance_definition.Config, this.granax_options, this.logger); let instance = new TorProcess(this.tor_path, instance_definition.Config, this.granax_options, this.logger);
instance.id = instance_id; instance.id = instance_id;
instance.definition = instance_definition; instance.definition = instance_definition;
instance.create((error) => {
if (error) return callback(error); await instance.create();
this._instances.push(instance);
this._instances.push(instance);
return new Promise((resolve, reject) => {
instance.once('error', reject);
instance.once('error', callback)
instance.once('ready', () => { instance.once('ready', () => {
this.emit('instance_created', instance); this.emit('instance_created', instance);
callback && callback(null, instance); resolve(instance);
}); });
}); });
} }
add(instance_definitions, callback) { async add(instance_definitions) {
async.each(instance_definitions, (instance_definition, next) => { return await Promise.all(instance_definitions.map((instance_definition) => this.create_instance(instance_definition)));
this.create_instance(instance_definition, next);
}, (callback || (() => {})));
} }
create(instances, callback) { async create(instances) {
if (typeof(instances) === 'number') { if (typeof(instances) === 'number') {
instances = Array.from(Array(instances)).map(() => { instances = Array.from(Array(instances)).map(() => {
return { return {
@ -97,7 +102,7 @@ class TorPool extends EventEmitter {
}; };
}); });
} }
return this.add(instances, callback); return await this.add(instances);
} }
instance_by_name(name) { instance_by_name(name) {
@ -108,28 +113,25 @@ class TorPool extends EventEmitter {
return this.instances[index]; return this.instances[index];
} }
remove(instances, callback) { async remove(instances) {
this._instances._weighted_list = void(0); this._instances._weighted_list = void(0);
let instances_to_remove = this._instances.splice(0, instances); let instances_to_remove = this._instances.splice(0, instances);
async.each(instances_to_remove, (instance, next) => { await Promise.all(instances_to_remove.map((instance) => instance.exit()));
instance.exit(next);
}, callback);
} }
remove_at(instance_index, callback) { async remove_at(instance_index) {
this._instances._weighted_list = void(0); this._instances._weighted_list = void(0);
let instance = this._instances.splice(instance_index, 1)[0]; let instance = this._instances.splice(instance_index, 1)[0];
instance.exit((error) => { await instance.exit();
callback(error);
});
} }
remove_by_name(instance_name, callback) { async remove_by_name(instance_name) {
let instance = this.instance_by_name(instance_name); let instance = this.instance_by_name(instance_name);
if (!instance) return callback && callback(new Error(`Instance "${name}" not found`)); if (!instance)
throw new Error(`Instance "${name}" not found`);
let instance_index = (this.instances.indexOf(instance)); let instance_index = (this.instances.indexOf(instance));
return this.remove_at(instance_index, callback); await this.remove_at(instance_index);
} }
next() { next() {
@ -137,103 +139,83 @@ class TorPool extends EventEmitter {
return this.instances[0]; return this.instances[0];
} }
exit(callback) { async exit() {
async.until(() => { return this._instances.length === 0; }, (next) => { await Promise.all(this._instances.map((instance) => instance.exit()));
var instance = this._instances.shift(); this._instances = [];
instance.exit(next);
}, (error) => {
callback && callback(error);
});
} }
new_identites(callback) { async new_identites() {
async.each(this.instances, (tor, next) => { await Promise.all(this.instances.map((instance) => instance.new_identity(next)));
tor.new_identity(next);
}, (error) => {
callback && callback(error);
});
} }
new_identity_at(index, callback) { async new_identity_at(index) {
this.instances[index].new_identity(callback); await this.instances[index].new_identity();
} }
new_identity_by_name(name, callback) { async new_identity_by_name(name) {
let instance = this.instance_by_name(name); let instance = this.instance_by_name(name);
if (!instance) return callback && callback(new Error(`Instance "${name}" not found`));
instance.new_identity(callback); if (!instance)
throw new Error(`Instance "${name}" not found`);
await instance.new_identity();
} }
/* Begin Deprecated */
new_ips(callback) { async get_config_by_name(name, keyword) {
this.logger.warn(`TorPool.new_ips is deprecated, use TorPool.new_identites`);
return this.new_identites(callback);
}
new_ip_at(index, callback) {
this.logger.warn(`TorPool.new_ip_at is deprecated, use TorPool.new_identity_at`);
return this.new_identity_at(index, callback);
}
/* End Deprecated */
get_config_by_name(name, keyword, callback) {
let instance = this.instance_by_name(name); let instance = this.instance_by_name(name);
if (!instance) return callback && callback(new Error(`Instance "${name}" not found`)); if (!instance)
instance.get_config(keyword, callback); throw new Error(`Instance "${name}" not found`);
return await instance.get_config(keyword);
} }
set_config_by_name(name, keyword, value, callback) { async set_config_by_name(name, keyword, value) {
let instance = this.instance_by_name(name); let instance = this.instance_by_name(name);
if (!instance) return callback && callback(new Error(`Instance "${name}" not found`)); if (!instance)
instance.set_config(keyword, value, callback); throw new Error(`Instance "${name}" not found`);
return await instance.set_config(keyword, value);
} }
get_config_at(index, keyword, callback) { async get_config_at(index, keyword) {
let instance = this.instances[index]; let instance = this.instances[index];
if (!instance) return callback && callback(new Error(`Instance at ${index} not found`)); if (!instance)
instance.get_config(keyword, callback); throw new Error(`Instance at ${index} not found`);
return await instance.get_config(keyword);
} }
set_config_at(index, keyword, value, callback) { async set_config_at(index, keyword, value) {
let instance = this.instances[index]; let instance = this.instances[index];
if (!instance) return callback && callback(new Error(`Instance at ${index} not found`)); if (!instance)
instance.set_config(keyword, value, callback); throw new Error(`Instance at ${index} not found`);
return await instance.set_config(keyword, value);
} }
set_config_all(keyword, value, callback) { async set_config_all(keyword, value) {
var i = 0; return await Promise.all(this.instances.map((instance) => instance.set_config(keyword, value)));
async.until(() => { return i === this.instances.length; }, (next) => {
let instance = this.instances[i++];
instance.set_config(keyword, value, (error) => {
next(error);
});
}, (error) => {
callback(error);
});
} }
signal_all(signal, callback) { async signal_all(signal) {
async.each(this.instances, (instance, next) => { await Promise.all(this.instances.map((instance) => instance.signal(signal, next)));
instance.signal(signal, next);
}, callback);
} }
signal_by_name(name, signal, callback) { async signal_by_name(name, signal) {
let instance = this.instance_by_name(name); let instance = this.instance_by_name(name);
if (!instance) return callback && callback(new Error(`Instance "${name}" not found`)); if (!instance)
instance.signal(signal, callback); throw new Error(`Instance "${name}" not found`);
await instance.signal(signal);
} }
signal_at(index, signal, callback) { async signal_at(index, signal) {
let instance = this.instances[index]; let instance = this.instances[index];
if (!instance) return callback && callback(new Error(`Instance at ${index} not found`)); if (!instance)
instance.signal(signal, callback); throw new Error(`Instance at ${index} not found`);
await instance.signal(signal);
} }
}; };
TorPool.LoadBalanceMethods = load_balance_methods;
module.exports = TorPool; module.exports = TorPool;

View file

@ -16,7 +16,7 @@ temp.track();
class TorProcess extends EventEmitter { class TorProcess extends EventEmitter {
constructor(tor_path, config, granax_options, logger) { constructor(tor_path, config, granax_options, logger) {
super(); super();
this.logger = logger; this.logger = logger || require('./winston-silent-logger');
this.tor_path = tor_path; this.tor_path = tor_path;
this.granax_options = granax_options; this.granax_options = granax_options;
this.control_password = crypto.randomBytes(128).toString('base64'); this.control_password = crypto.randomBytes(128).toString('base64');

View file

@ -0,0 +1,6 @@
module.exports = require('winston').createLogger({
level: 'info',
format: winston.format.simple(),
silent: true,
transports: [ new (winston.transports.Console)({ silent: true }) ]
});

View file

@ -11,17 +11,12 @@ const del = require('del');
const rpc = require('jrpc2'); const rpc = require('jrpc2');
const fs = require('fs'); const fs = require('fs');
var colors = require('mocha/lib/reporters/base').colors; const colors = require('mocha/lib/reporters/base').colors;
var nconf = require('nconf'); const nconf = require('nconf');
nconf = require(`${__dirname}/../src/nconf_load_env.js`)(nconf); nconf = require(`${__dirname}/../src/nconf_load_env.js`)(nconf);
nconf.defaults(require(`${__dirname}/../src/default_config.js`)); nconf.defaults(require(`${__dirname}/../src/default_config.js`));
var logger = winston.createLogger({ const logger = require('../src/winston-silent-logger');
level: 'info',
format: winston.format.simple(),
silent: true,
transports: [ new (winston.transports.Console)({ silent: true }) ]
});
const WAIT_FOR_CREATE = 120000; const WAIT_FOR_CREATE = 120000;
const PAGE_LOAD_TIME = 60000; const PAGE_LOAD_TIME = 60000;