Some work on website/api
This commit is contained in:
parent
5acaaa5686
commit
6899186dc3
|
@ -7,5 +7,10 @@
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"port": 8117,
|
"port": 8117,
|
||||||
"password": "test"
|
"password": "test"
|
||||||
|
},
|
||||||
|
"website": {
|
||||||
|
"enabled": true,
|
||||||
|
"port": 80,
|
||||||
|
"liveStats": true
|
||||||
}
|
}
|
||||||
}
|
}
|
25
init.js
25
init.js
|
@ -9,6 +9,7 @@ var BlocknotifyListener = require('./libs/blocknotifyListener.js');
|
||||||
var WorkerListener = require('./libs/workerListener.js');
|
var WorkerListener = require('./libs/workerListener.js');
|
||||||
var PoolWorker = require('./libs/poolWorker.js');
|
var PoolWorker = require('./libs/poolWorker.js');
|
||||||
var PaymentProcessor = require('./libs/paymentProcessor.js');
|
var PaymentProcessor = require('./libs/paymentProcessor.js');
|
||||||
|
var Website = require('./libs/website.js');
|
||||||
|
|
||||||
JSON.minify = JSON.minify || require("node-json-minify");
|
JSON.minify = JSON.minify || require("node-json-minify");
|
||||||
|
|
||||||
|
@ -48,6 +49,9 @@ if (cluster.isWorker){
|
||||||
case 'paymentProcessor':
|
case 'paymentProcessor':
|
||||||
new PaymentProcessor(loggerInstance);
|
new PaymentProcessor(loggerInstance);
|
||||||
break;
|
break;
|
||||||
|
case 'website':
|
||||||
|
new Website(loggerInstance);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -145,7 +149,24 @@ var startPaymentProcessor = function(poolConfigs){
|
||||||
worker.on('exit', function(code, signal){
|
worker.on('exit', function(code, signal){
|
||||||
logError('paymentProcessor', 'system', 'Payment processor died, spawning replacement...');
|
logError('paymentProcessor', 'system', 'Payment processor died, spawning replacement...');
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
startPaymentProcessor(poolConfigs);
|
startPaymentProcessor.apply(null, arguments);
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var startWebsite = function(portalConfig, poolConfigs){
|
||||||
|
if (!portalConfig.website.enabled) return;
|
||||||
|
|
||||||
|
var worker = cluster.fork({
|
||||||
|
workerType: 'website',
|
||||||
|
pools: JSON.stringify(poolConfigs),
|
||||||
|
portalConfig: JSON.stringify(portalConfig)
|
||||||
|
});
|
||||||
|
worker.on('exit', function(code, signal){
|
||||||
|
logError('website', 'system', 'Website process died, spawning replacement...');
|
||||||
|
setTimeout(function(){
|
||||||
|
startWebsite.apply(null, arguments);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -165,4 +186,6 @@ var startPaymentProcessor = function(poolConfigs){
|
||||||
|
|
||||||
startWorkerListener(poolConfigs);
|
startWorkerListener(poolConfigs);
|
||||||
|
|
||||||
|
startWebsite(portalConfig, poolConfigs);
|
||||||
|
|
||||||
})();
|
})();
|
|
@ -5,7 +5,7 @@ var app = express();
|
||||||
app.get('/getstatus', function (req, res) {
|
app.get('/getstatus', function (req, res) {
|
||||||
res.send({
|
res.send({
|
||||||
'loadavg': os.loadavg(),
|
'loadavg': os.loadavg(),
|
||||||
'freemem': os.freemem(),
|
'freemem': os.freemem()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -211,7 +211,7 @@ function SetupForPool(logger, poolOptions){
|
||||||
callback('done - redis error with multi get rounds share')
|
callback('done - redis error with multi get rounds share')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.dir(workerRewards);
|
|
||||||
|
|
||||||
var workerBalances = {};
|
var workerBalances = {};
|
||||||
|
|
||||||
|
@ -219,7 +219,6 @@ function SetupForPool(logger, poolOptions){
|
||||||
workerBalances[workers[i]] = parseInt(results[i]) || 0;
|
workerBalances[workers[i]] = parseInt(results[i]) || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.dir(workerBalances);
|
|
||||||
|
|
||||||
callback(null, rounds, workerRewards, workerBalances)
|
callback(null, rounds, workerRewards, workerBalances)
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,9 +19,6 @@ module.exports = function(logger, poolConfig){
|
||||||
var redisConfig = internalConfig.redis;
|
var redisConfig = internalConfig.redis;
|
||||||
var coin = poolConfig.coin.name;
|
var coin = poolConfig.coin.name;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var connection;
|
var connection;
|
||||||
|
|
||||||
function connect(){
|
function connect(){
|
||||||
|
@ -47,6 +44,13 @@ module.exports = function(logger, poolConfig){
|
||||||
connect();
|
connect();
|
||||||
|
|
||||||
|
|
||||||
|
//Every 10 minutes clear out old hashrate stat data from redis
|
||||||
|
setInterval(function(){
|
||||||
|
var tenMinutesAgo = (Date.now() / 1000 | 0) - (60 * 10);
|
||||||
|
connection.zremrangebyscore([coin + '_hashrate', '-inf', tenMinutesAgo]);
|
||||||
|
}, 10 * 60 * 1000);
|
||||||
|
|
||||||
|
|
||||||
this.handleShare = function(isValidShare, isValidBlock, shareData){
|
this.handleShare = function(isValidShare, isValidBlock, shareData){
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,6 +62,10 @@ module.exports = function(logger, poolConfig){
|
||||||
for more efficient stats
|
for more efficient stats
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//store share diff, worker, and unique value with a score that is the timestamp
|
||||||
|
//unique value ensures it doesnt overwrite an existing entry
|
||||||
|
//the timestamp as score lets us query shares from last X minutes to generate hashrate for each worker and pool
|
||||||
|
connection.zadd(coin + '_hashrate', Date.now() / 1000 | 0, shareData.difficulty + ':' + shareData.worker + ':' + Math.random());
|
||||||
|
|
||||||
connection.hincrby([coin + '_shares:roundCurrent', shareData.worker, shareData.difficulty], function(error, result){
|
connection.hincrby([coin + '_shares:roundCurrent', shareData.worker, shareData.difficulty], function(error, result){
|
||||||
if (error)
|
if (error)
|
||||||
|
|
|
@ -1,12 +1,67 @@
|
||||||
/* TODO
|
/* TODO
|
||||||
|
|
||||||
listen on port 80 for requests, maybe use express.
|
|
||||||
read website folder files into memory, and use fs.watch to reload changes to any files into memory
|
|
||||||
|
|
||||||
on some interval, apply a templating process to it with the latest api stats. on http requests, serve
|
Need to condense the entire website into a single html page. Embedding the javascript and css is easy. For images,
|
||||||
this templated file and the other resources in memory.
|
hopefully we can only use svg which can be embedded - otherwise we can convert the image into a data-url that can
|
||||||
|
be embedded, Favicon can also be a data-url which some javascript kungfu can display in browser. I'm focusing on
|
||||||
|
this mainly to help mitigate ddos and other kinds of attacks - and to just have a badass blazing fast project.
|
||||||
|
|
||||||
ideally, all css/js should be included in the html file (try to avoid images, uses embeddable svg)
|
Don't worry about doing any of that condensing yourself - go head and keep all the resources as separate files.
|
||||||
this would give us one file to have to serve
|
I will write a script for when the server starts to read all the files in the /website folder and minify and condense
|
||||||
|
it all together into one file, saved in memory. We will have 1 persistent condensed file that servers as our "template"
|
||||||
|
file that contains things like:
|
||||||
|
<div>Hashrate: {{=stats.hashrate}</div>
|
||||||
|
|
||||||
|
And then on some caching interval (maybe 5 seconds?) we will apply the template engine to generate the real html page
|
||||||
|
that we serve and hold in in memory - this is the file we serve to seo-bots (googlebot) and users when they first load
|
||||||
|
the page.
|
||||||
|
|
||||||
|
Once the user loads the page we will have server-side event source connected to the portal api where it receives
|
||||||
|
updated stats on some interval (probably 5 seconds like template cache updater) and applies the changes to the already
|
||||||
|
displayed page.
|
||||||
|
|
||||||
|
We will use fs.watch to detect changes to anything in the /website folder and update our stuff in memory.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
var dot = require('dot');
|
||||||
|
var express = require('express');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = function(logger){
|
||||||
|
|
||||||
|
var portalConfig = JSON.parse(process.env.portalConfig);
|
||||||
|
var poolConfigs = JSON.parse(process.env.pools);
|
||||||
|
|
||||||
|
var logIdentify = 'Website';
|
||||||
|
|
||||||
|
var websiteLogger = {
|
||||||
|
debug: function(key, text){
|
||||||
|
logger.logDebug(logIdentify, key, text);
|
||||||
|
},
|
||||||
|
warning: function(key, text){
|
||||||
|
logger.logWarning(logIdentify, key, text);
|
||||||
|
},
|
||||||
|
error: function(key, text){
|
||||||
|
logger.logError(logIdentify, key, text);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
app.get('/', function(req, res){
|
||||||
|
res.send('hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(function(err, req, res, next){
|
||||||
|
console.error(err.stack);
|
||||||
|
res.send(500, 'Something broke!');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(portalConfig.website.port, function(){
|
||||||
|
websiteLogger.debug('system', 'Website started on port ' + portalConfig.website.port);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
};
|
|
@ -37,7 +37,9 @@
|
||||||
"posix": "*",
|
"posix": "*",
|
||||||
"redis": "*",
|
"redis": "*",
|
||||||
"mysql": "*",
|
"mysql": "*",
|
||||||
"async": "*"
|
"async": "*",
|
||||||
|
"express": "*",
|
||||||
|
"dot": "*"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
|
|
Loading…
Reference in New Issue