jenkins-bot has submitted this change and it was merged.
Change subject: Improve apiServer.js to support multiple mock and Parsoid
servers
......................................................................
Improve apiServer.js to support multiple mock and Parsoid servers
Instead of just managing a single server, keep a map of them so
that multiple servers can be started from a single process. This
is necessary, for example, to test the Parsoid API using a mock MW
server.
Change-Id: I19f8dd106dc32095c07ce38e8c02eaf1f60d8ee4
---
M api/server.js
M tests/apiServer.js
M tests/mockAPI.js
3 files changed, 69 insertions(+), 29 deletions(-)
Approvals:
Subramanya Sastry: Looks good to me, approved
jenkins-bot: Verified
diff --git a/api/server.js b/api/server.js
index ae98aab..f28a9b0 100755
--- a/api/server.js
+++ b/api/server.js
@@ -156,10 +156,13 @@
} else {
// Worker
- process.on('SIGTERM', function() {
+ var shutdown_worker = function () {
logger.log( "warning", "shutting down" );
process.exit(0);
- });
+ };
+
+ process.on('SIGTERM', shutdown_worker);
+ process.on('disconnect', shutdown_worker);
// Enable heap dumps in /tmp on kill -USR2.
// See https://github.com/bnoordhuis/node-heapdump/
diff --git a/tests/apiServer.js b/tests/apiServer.js
index acdd5e1..39fd84c 100644
--- a/tests/apiServer.js
+++ b/tests/apiServer.js
@@ -6,22 +6,40 @@
* Uses port randomization to make sure we can use multiple servers
concurrently.
*/
+require('es6-shim');
+
var child_process = require( 'child_process' ),
Util = require('../lib/mediawiki.Util.js').Util,
path = require( 'path' );
-var forkedServer;
-var forkedServerURL;
+// Keep all started servers in a map indexed by the url
+var forkedServers = new Map(),
+ exiting = false;
-var stopServer = function () {
- if ( forkedServer ) {
- forkedServer.kill();
+var stopServer = function (url) {
+ var forkedServer = forkedServers.get(url);
+ if (forkedServer) {
+ // Prevent restart if we explicitly stop it
+ forkedServer.child.removeAllListeners('exit');
+ forkedServer.child.kill();
+ forkedServers.delete(url);
}
};
+var stopAllServers = function () {
+ forkedServers.forEach(function (forkedServer, url) {
+ stopServer(url);
+ });
+};
+
/**
- * Make sure the server is killed if the process exits.
+ * Make sure the servers are killed if the process exits.
*/
+process.on('exit', function() {
+ exiting = true;
+ stopAllServers();
+});
+
var exitOnProcessTerm = function (res) {
var stopAndExit = function () {
process.exit(res || 0);
@@ -38,23 +56,30 @@
* Starts a server on passed port or a random port if none passed.
* The callback will get the URL of the started server.
*/
-var startServer = function ( opts, cb, port ) {
+var startServer = function ( opts, cb, retrying ) {
+ var url, forkedServer = {}, port;
if (!opts) {
throw "Please provide server options.";
}
+ forkedServer.opts = opts;
+ port = opts.port;
// For now, we always assume that retries are due to port conflicts
- if (!port || opts.retrying) {
+ if (!port) {
port = opts.portBase + Math.floor( Math.random() * 100 );
}
- forkedServerURL = 'http://' + opts.iface + ':' + port.toString() +
opts.urlPath;
-
- if (!opts.quiet) {
- console.log( "Starting " + opts.serverName + " server at",
forkedServerURL );
+ url = 'http://' + opts.iface + ':' + port.toString() + opts.urlPath;
+ if (opts.port && forkedServers.has(url)) {
+ // We already have a server there!
+ throw "There's already a server running at that port.";
}
- forkedServer = child_process.fork(__dirname + opts.filePath,
+ if (!opts.quiet) {
+ console.log( "Starting %s server at %s", opts.serverName, url );
+ }
+
+ forkedServer.child = child_process.fork(__dirname + opts.filePath,
opts.serverArgv,
{
env: {
@@ -65,18 +90,21 @@
}
);
- // If it dies on its own, restart it
- forkedServer.on( 'exit', function( ) {
- console.warn('apiServer quit; retry with a different port');
- forkedServer = null;
- opts.retrying = true;
- startServer(opts, cb);
- } );
+ forkedServers.set(url, forkedServer);
- if (!opts.retrying) {
- // If this process dies, kill our server
- process.on( 'exit', stopServer );
+ // If it dies on its own, restart it. The most common cause will be
that the
+ // port was already in use, so if no port was specified then a new
random
+ // one will be selected.
+ forkedServer.child.on('exit', function (exitUrl) {
+ if (exiting) {
+ return;
+ }
+ console.warn('Restarting server at', exitUrl);
+ forkedServers.delete(exitUrl);
+ startServer(opts, cb, true);
+ }.bind(null, url));
+ if (!retrying) {
// HACK HACK HACK!!
//
// It is possible that we get into this callback in the time
@@ -91,8 +119,8 @@
// the server url. But, that is more work and it is unclear
// if we need it.
var waitAndCB = function() {
- if (forkedServer) {
- cb(forkedServerURL, forkedServer);
+ if (forkedServer.child) {
+ cb(url, forkedServer.child);
} else {
setTimeout(waitAndCB, 2000);
}
@@ -118,7 +146,7 @@
var startParsoidServer = function (opts, cb) {
opts = !opts ? parsoidServerOpts : Util.extendProps(opts,
parsoidServerOpts);
- startServer(opts, cb, opts.port);
+ startServer(opts, cb);
};
var mockAPIServerOpts = {
@@ -133,12 +161,13 @@
var startMockAPIServer = function (opts, cb) {
opts = !opts ? mockAPIServerOpts : Util.extendProps(opts,
mockAPIServerOpts);
- startServer(opts, cb, opts.port);
+ startServer(opts, cb);
};
module.exports = {
startServer: startServer,
stopServer: stopServer,
+ stopAllServers: stopAllServers,
startParsoidServer: startParsoidServer,
startMockAPIServer: startMockAPIServer,
exitOnProcessTerm: exitOnProcessTerm
diff --git a/tests/mockAPI.js b/tests/mockAPI.js
index eeab255..f405063 100644
--- a/tests/mockAPI.js
+++ b/tests/mockAPI.js
@@ -94,7 +94,15 @@
cb( null, { parse: { text: { '*': resultText } } } );
},
+ querySiteinfo: function( body, cb ) {
+ // TODO: Read which language should we use from
somewhere.
+ cb( null, require('../lib/baseconfig/enwiki.json') );
+ },
+
query: function ( body, cb ) {
+ if (body.meta === 'siteinfo') {
+ return this.querySiteinfo( body, cb );
+ }
var filename = body.titles,
normPagename = pnames[filename] || filename,
normFilename = fnames[filename] || filename;
--
To view, visit https://gerrit.wikimedia.org/r/172752
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I19f8dd106dc32095c07ce38e8c02eaf1f60d8ee4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Marcoil <[email protected]>
Gerrit-Reviewer: Arlolra <[email protected]>
Gerrit-Reviewer: Cscott <[email protected]>
Gerrit-Reviewer: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits