mirror of https://github.com/BTCPrivate/z-nomp.git
139 lines
3.9 KiB
JavaScript
139 lines
3.9 KiB
JavaScript
var fs = require('fs');
|
|
var os = require('os');
|
|
var cluster = require('cluster');
|
|
|
|
|
|
var posix = require('posix');
|
|
var PoolLogger = require('./libs/logutils.js');
|
|
var BlocknotifyListener = require('./libs/blocknotifyListener.js');
|
|
var WorkerListener = require('./libs/workerListener.js');
|
|
var PoolWorker = require('./libs/poolWorker.js');
|
|
|
|
JSON.minify = JSON.minify || require("node-json-minify");
|
|
|
|
|
|
|
|
//Try to give process ability to handle 100k concurrent connections
|
|
try{
|
|
posix.setrlimit('nofile', { soft: 100000, hard: 100000 });
|
|
}
|
|
catch(e){
|
|
console.error(e);
|
|
}
|
|
|
|
|
|
|
|
var loggerInstance = new PoolLogger({
|
|
'default': true,
|
|
'keys': {
|
|
//'client' : 'warning',
|
|
'system' : true,
|
|
'submitblock' : true
|
|
}
|
|
});
|
|
|
|
var logDebug = loggerInstance.logDebug;
|
|
var logWarning = loggerInstance.logWarning;
|
|
var logError = loggerInstance.logError;
|
|
|
|
|
|
|
|
if (cluster.isMaster){
|
|
|
|
|
|
var config = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
|
|
|
|
//Read all coin profile json files from coins directory and build object where key is name of coin
|
|
var coinProfiles = (function(){
|
|
var profiles = {};
|
|
fs.readdirSync('coins').forEach(function(file){
|
|
var coinProfile = JSON.parse(JSON.minify(fs.readFileSync('coins/' + file, {encoding: 'utf8'})));
|
|
profiles[coinProfile.name.toLowerCase()] = coinProfile;
|
|
});
|
|
return profiles;
|
|
})();
|
|
|
|
|
|
//Read all pool configs from pool_configs and join them with their coin profile
|
|
var poolConfigs = (function(){
|
|
var configs = {};
|
|
fs.readdirSync('pool_configs').forEach(function(file){
|
|
var poolOptions = JSON.parse(JSON.minify(fs.readFileSync('pool_configs/' + file, {encoding: 'utf8'})));
|
|
if (poolOptions.disabled) return;
|
|
if (!(poolOptions.coin.toLowerCase() in coinProfiles)){
|
|
logError(poolOptions.coin, 'system', 'could not find coin profile');
|
|
return;
|
|
}
|
|
poolOptions.coin = coinProfiles[poolOptions.coin.toLowerCase()];
|
|
configs[poolOptions.coin.name] = poolOptions;
|
|
});
|
|
return configs;
|
|
})();
|
|
|
|
|
|
var serializedConfigs = JSON.stringify(poolConfigs);
|
|
|
|
|
|
var numForks = (function(){
|
|
if (!config.clustering || !config.clustering.enabled)
|
|
return 1;
|
|
if (config.clustering.forks === 'auto')
|
|
return os.cpus().length;
|
|
if (!config.clustering.forks || isNaN(config.clustering.forks))
|
|
return 1;
|
|
return config.clustering.forks;
|
|
})();
|
|
|
|
var workerIds = {};
|
|
|
|
for (var i = 0; i < numForks; i++) {
|
|
var worker = cluster.fork({
|
|
forkId: i,
|
|
pools: serializedConfigs
|
|
});
|
|
workerIds[worker.process.pid] = i;
|
|
}
|
|
|
|
cluster.on('exit', function(worker, code, signal) {
|
|
var diedPid = worker.process.pid;
|
|
var forkId = workerIds[diedPid]
|
|
logError('poolWorker', 'system', 'Fork ' + forkId + ' died, spawning replacement worker...');
|
|
var worker = cluster.fork({
|
|
forkId: forkId,
|
|
pools: serializedConfigs
|
|
});
|
|
delete workerIds[diedPid];
|
|
workerIds[worker.process.pid] = forkId;
|
|
});
|
|
|
|
|
|
|
|
var workerListener = new WorkerListener(loggerInstance, poolConfigs);
|
|
workerListener.init();
|
|
|
|
|
|
|
|
//block notify options
|
|
//setup block notify here and use IPC to tell appropriate pools
|
|
var listener = new BlocknotifyListener(config.blockNotifyListener);
|
|
listener.on('log', function(text){
|
|
logDebug('blocknotify', 'system', text);
|
|
});
|
|
listener.on('hash', function(message){
|
|
|
|
var ipcMessage = {type:'blocknotify', coin: message.coin, hash: message.hash};
|
|
Object.keys(cluster.workers).forEach(function(id) {
|
|
cluster.workers[id].send(ipcMessage);
|
|
});
|
|
|
|
});
|
|
listener.start();
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
var worker = new PoolWorker(loggerInstance);
|
|
|
|
}
|