Skip to content
Snippets Groups Projects
Commit 58668a77 authored by Lloyd Hilaiel's avatar Lloyd Hilaiel
Browse files

keysigner to saturate multiple cores - issue #213

parent 23cd4da0
No related branches found
No related tags found
No related merge requests found
......@@ -47,9 +47,9 @@ httputils = require('../lib/httputils.js'),
validate = require('../lib/validate.js'),
metrics = require('../lib/metrics.js'),
logger = require('../lib/logging.js').logger,
ca = require('../lib/keysigner/ca.js'),
heartbeat = require('../lib/heartbeat'),
shutdown = require('../lib/shutdown');
shutdown = require('../lib/shutdown'),
computecluster = require('compute-cluster');
// create an express server
var app = express.createServer();
......@@ -84,32 +84,51 @@ app.use(function(req, resp, next) {
// parse POST bodies
app.use(express.bodyParser());
// allocate a compute cluster
try {
var cc = new computecluster({
module: path.join(__dirname, "..", "lib", "keysigner", "subprocess.js"),
max_processes: config.get('max_compute_processes')
}).on('error', function(e) {
logger.error("error detected in keysigning computation process! fatal: " + e.toString());
setTimeout(function() { process.exit(1); }, 0);
}).on('info', function(msg) {
logger.info("(compute cluster): " + msg);
}).on('debug', function(msg) {
logger.debug("(compute cluster): " + msg);
});
} catch(e) {
process.stderr.write("can't allocate compute cluster: " + e + "\n");
process.exit(1);
}
// and our single function
app.post('/wsapi/cert_key', validate(["email", "pubkey"]), function(req, resp) {
try {
// parse the pubkey
var pk = ca.parsePublicKey(req.body.pubkey);
// same account, we certify the key
// we certify it for a day for now
var expiration = new Date();
expiration.setTime(new Date().valueOf() + config.get('certificate_validity_ms'));
var cert = ca.certify(req.body.email, pk, expiration);
resp.writeHead(200, {'Content-Type': 'text/plain'});
resp.write(cert);
resp.end();
} catch (e) {
logger.error("certification generation error: " + e.toString());
httputils.serverError(resp, "certification generation error");
}
cc.enqueue({
pubkey: req.body.pubkey,
email: req.body.email
}, function (err, r) {
// consider "application" errors to be the same as harder errors
if (!err && r && r.error) err = r.error;
if (!r || !r.success) err = "no certificate returned from child process";
if (err) {
logger.error("certification generation error: " + err);
httputils.serverError(resp, "certification generation error");
} else {
resp.writeHead(200, {'Content-Type': 'text/plain'});
resp.write(r.success);
resp.end();
}
});
});
// shutdown when code_update is invoked
shutdown.installUpdateHandler(app);
// shutdown nicely on signals
shutdown.handleTerminationSignals(app);
shutdown.handleTerminationSignals(app, function() {
cc.exit();
});
var bindTo = config.get('bind_to');
app.listen(bindTo.port, bindTo.host, function() {
......
......@@ -104,7 +104,9 @@ g_configs.production = {
bcrypt_work_factor: 12,
authentication_duration_ms: (2 * 7 * 24 * 60 * 60 * 1000),
certificate_validity_ms: (24 * 60 * 60 * 1000),
min_time_between_emails_ms: (60 * 1000)
min_time_between_emails_ms: (60 * 1000),
// may be specified to manipulate the maximum number of compute
max_compute_processes: undefined
};
......@@ -121,7 +123,8 @@ g_configs.local = {
bcrypt_work_factor: g_configs.production.bcrypt_work_factor,
authentication_duration_ms: g_configs.production.authentication_duration_ms,
certificate_validity_ms: g_configs.production.certificate_validity_ms,
min_time_between_emails_ms: g_configs.production.min_time_between_emails_ms
min_time_between_emails_ms: g_configs.production.min_time_between_emails_ms,
max_compute_processes: undefined
};
// test environments are variations on local
......@@ -204,6 +207,12 @@ if (process.env['BCRYPT_WORK_FACTOR']) {
g_config.bcrypt_work_factor = parseInt(process.env['BCRYPT_WORK_FACTOR']);
}
// allow the number of cores used to be specified from the environment,
// default will something reasonable.
if (process.env['MAX_COMPUTE_PROCESSES']) {
g_config.max_compute_processes = parseInt(process.env['MAX_COMPUTE_PROCESSES']);
}
// what host/port shall we bind to?
g_config.bind_to = {
host: process.env['IP_ADDRESS'] || process.env['HOST'] || "127.0.0.1",
......
const
config = require('../configuration'),
ca = require('./ca.js');
process.on('message', function(m) {
try {
// parse the pubkey
var pk = ca.parsePublicKey(m.pubkey);
// same account, we certify the key
// we certify it for a day for now
var expiration = new Date();
expiration.setTime(new Date().valueOf() + config.get('certificate_validity_ms'));
var cert = ca.certify(m.email, pk, expiration);
process.send({"success": cert});
} catch(e) {
process.send({"error": e ? e.toString() : "unknown"});
}
});
......@@ -32,6 +32,7 @@
, "node-statsd": "https://github.com/mojodna/node-statsd/tarball/2584c08fad"
, "connect-logger-statsd": "0.0.1"
, "semver": "1.0.12"
, "compute-cluster": "0.0.2"
}
, "scripts": {
"postinstall": "./scripts/generate_ephemeral_keys.sh",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment