From 87f4215a207ddf581e640288fa44575ba46452be Mon Sep 17 00:00:00 2001 From: Manuel Escudero Date: Sat, 18 Apr 2015 02:19:41 -0500 Subject: [PATCH] Updated test/utils/server.js for compatibility with express 4.x and added multi-threading capabilities via the cluster module --- test/utils/server.js | 152 ++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 67 deletions(-) diff --git a/test/utils/server.js b/test/utils/server.js index 2aae369..e033a84 100644 --- a/test/utils/server.js +++ b/test/utils/server.js @@ -1,81 +1,99 @@ 'use strict'; -var async = require('async'); -var express = require('express'); -var fs = require('fs'); -var multiparty = require('multiparty'); -var util = require('util'); +var app, async, cluster, cpuCount, express, fs, http, i, multiparty, port, server, util; +express = require('express'); +cluster = require('cluster'); +http = require('http'); +async = require('async'); +fs = require('fs'); +multiparty = require('multiparty'); +util = require('util'); -/* Make an http server to receive the webhook. */ -var server = express(); -server.use(server.router); - -server.head('/webhook', function (req, res) { +/* Start cluster to take advantage of multi-core servers */ +if (cluster.isMaster) { + cpuCount = require('os').cpus().length; + i = 0; + while (i < cpuCount) { + cluster.fork(); + i += 1; + } +} else { + /* Make an http server to receive the webhook. */ + app = express(); + port = 3000; + server = app.listen(port); + app.head('/webhook', function(req, res) { console.log('Received head request from webhook.'); - res.send(200); -}); - -server.post('/webhook', function (req, res) { + res.sendStatus(200); + }); + app.post('/webhook', function(req, res) { + var form; console.log('Receiving webhook.'); /* Respond early to avoid timouting the mailin server. */ - // res.send(200); - /* Parse the multipart form. The attachments are parsed into fields and can - * be huge, so set the maxFieldsSize accordingly. */ - var form = new multiparty.Form({ - maxFieldsSize: 70000000 + * be huge, so set the maxFieldsSize accordingly. + */ + form = new multiparty.Form({ + maxFieldsSize: 70000000 }); + form.on('progress', (function() { + var lastDisplayedPercentage, start; + start = Date.now(); + lastDisplayedPercentage = -1; + return function(bytesReceived, bytesExpected) { + var elapsed, percentage; + elapsed = Date.now() - start; + percentage = Math.floor(bytesReceived / bytesExpected * 100); + if (percentage % 20 === 0 && percentage !== lastDisplayedPercentage) { + lastDisplayedPercentage = percentage; + console.log('Form upload progress ' + percentage + '% of ' + bytesExpected / 1000000 + 'Mb. ' + elapsed + 'ms'); + } + }; + })()); + form.parse(req, function(err, fields) { + console.log(util.inspect(fields.mailinMsg, { + depth: 5 + })); + console.log('Parsed fields: ' + Object.keys(fields)); - form.on('progress', function () { - var start = Date.now(); - var lastDisplayedPercentage = -1; - return function (bytesReceived, bytesExpected) { - var elapsed = Date.now() - start; - var percentage = Math.floor(bytesReceived / bytesExpected * 100); - if (percentage % 20 === 0 && percentage !== lastDisplayedPercentage) { - lastDisplayedPercentage = percentage; - console.log('Form upload progress ' + - percentage + '% of ' + bytesExpected / 1000000 + 'Mb. ' + elapsed + 'ms'); - } - }; - }()); - - form.parse(req, function (err, fields) { - console.log(util.inspect(fields.mailinMsg, { - depth: 5 - })); - - console.log('Parsed fields: ' + Object.keys(fields)); - - /* Write down the payload for ulterior inspection. */ - async.auto({ - writeParsedMessage: function (cbAuto) { - fs.writeFile('payload.json', fields.mailinMsg, cbAuto); - }, - writeAttachments: function (cbAuto) { - var msg = JSON.parse(fields.mailinMsg); - async.eachLimit(msg.attachments, 3, function (attachment, cbEach) { - fs.writeFile(attachment.generatedFileName, fields[attachment.generatedFileName], 'base64', cbEach); - }, cbAuto); - } - }, function (err) { - if (err) { - console.log(err.stack); - res.send(500, 'Unable to write payload'); - } else { - console.log('Webhook payload written.'); - res.send(200); - } - }); + /* Write down the payload for ulterior inspection. */ + async.auto({ + writeParsedMessage: function(cbAuto) { + fs.writeFile('payload.json', fields.mailinMsg, cbAuto); + }, + writeAttachments: function(cbAuto) { + var msg; + msg = JSON.parse(fields.mailinMsg); + async.eachLimit(msg.attachments, 3, (function(attachment, cbEach) { + fs.writeFile(attachment.generatedFileName, fields[attachment.generatedFileName], 'base64', cbEach); + }), cbAuto); + } + }, function(err) { + if (err) { + console.log(err.stack); + res.status(500).send(err, "Unable to write payload"); + } else { + console.log('Webhook payload written.'); + res.sendStatus(200); + } + }); }); -}); + }); + http.createServer(app).listen(app.get(port), function() { + var cpuNum; + cpuNum = parseInt(cluster.worker.id) - 1; + cpuNum = cpuNum.toString(); + console.log('Express server listening on port ' + port + ', cpu:worker:' + cpuNum); + }); +} -server.listen(3000, function (err) { - if (err) { - console.log(err); - } else { - console.log('Http server listening on port 3000'); - } +/* Catch dying cluster threads and respawn them */ +cluster.on('exit', function(worker) { + var cpuNum; + cpuNum = parseInt(worker.id) - 1; + cpuNum = cpuNum.toString(); + console.log('cpu:worker:' + cpuNum + ' died unexpectedly, respawning...'); + cluster.fork(); });