Physikerwelt has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/87699


Change subject: WIP: Ideas to make the node worker more robust
......................................................................

WIP: Ideas to make the node worker more robust

Change-Id: If1d5ce7cf40932f9136f20fc3d06466cc67128d3
---
M mathoid/main.js
M mathoid/mathoid-worker.js
M mathoid/mathoid.js
3 files changed, 123 insertions(+), 35 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Math 
refs/changes/99/87699/1

diff --git a/mathoid/main.js b/mathoid/main.js
index 312d4d9..7aac22a 100644
--- a/mathoid/main.js
+++ b/mathoid/main.js
@@ -41,11 +41,12 @@
                        data[0].length + 'B query, ERR ' + data[1][0] + t;
                        out = JSON.stringify({err:data[1].message 
,'log':log,'sucess':false});
                        resp.write(out);
-                       console.log('error'+log);
+                       //console.log('error'+log);
                }catch(err){
                        true;
                }
                        //shutdown and wait for reboot
+               console.log('committing suicide on port '+PORT);
                phantom.exit(1);
        }
        resp.close();
@@ -72,7 +73,8 @@
       window.engine.process(q, window.callPhantom);
     }, query);
        }catch(err){
-               console.log('Unhandled error: ' + err.message);
+               //console.log('Unhandled error: ' + err.message);
+               console.log('committing suicide on port '+PORT);
                phantom.exit(1);
        }       
   });
@@ -86,5 +88,5 @@
     console.log(".. or by sending tex source in POST (not url encoded)");
   }*/
 });
-
+console.log('READY on port '+PORT);
 
diff --git a/mathoid/mathoid-worker.js b/mathoid/mathoid-worker.js
index dfedb3b..3b729a7 100644
--- a/mathoid/mathoid-worker.js
+++ b/mathoid/mathoid-worker.js
@@ -14,6 +14,17 @@
 
 var config;
 
+var ready = false;
+var starting = false;
+
+const STOPPED=0,
+       START_REQUEST=1,
+       STARTING=2,
+       START_SUCESS=3,
+       READY=4,
+       STOPREQUEST=5,
+       STOPPING=6;
+var state = STOPPED; 
 // Get the config
 try {
        config = JSON.parse(fs.readFileSync('./mathoid.config.json', 'utf8'));
@@ -44,27 +55,76 @@
        requestQueue = [];
 
 var startBackend = function () {
-       if (backend) {
-               backend.kill();
-       }
-       var backendCB = function (err, stdout, stderr) {
-               if (err) {
-                       restarts--;
-                       if (restarts > 0) {
-                               startBackend();
-                       }
-                       console.error(err.toString());
-                       process.exit(1);
+       if ( state == START_REQUEST ){
+               state = STARTING;
+               if (backend) {
+                       backend.kill();
                }
-       };
-       backendPort = Math.floor(9000 + Math.random() * 50000);
-       console.error(instanceName + ': Starting backend on port ' + 
backendPort);
-       backend = child_process.exec('phantomjs main.js ' + backendPort, 
backendCB);
-       backend.stdout.pipe(process.stdout);
-       backend.stderr.pipe(process.stderr);
+               backend = null;
+               var stdoutListener;
+               var backendCB = function (err, stdout, stderr) {
+                       if (err) {
+                               restarts--;
+                               if (restarts > 0) {
+                                       state = STOPREQUEST;
+                                       restartBackend();
+                               }
+                               console.error('Strange-Error'+err.toString());
+                               console.log('Restarts:'+restarts);
+                               //process.exit(1);
+                       }
+               };
+               var designatedBackendPort = Math.floor(9000 + Math.random() * 
50000);
+               backend = child_process.exec('phantomjs main.js ' + 
designatedBackendPort, backendCB);
+               console.error( instanceName + ': Starting backend on port ' + 
designatedBackendPort);
+               backend.stdout.pipe(process.stdout);
+               backend.stderr.pipe(process.stderr);
+               backend.stdout.on('data', function (data) {
+                       if (/^READY on port/.test(data)) {
+                               var pattern = /\d+/
+                               var port = parseInt(data.match(pattern));
+                               if ( state == STARTING){
+                                       state = START_SUCESS;
+                                       setTimeout(function(){
+                                               backendPort= port;
+                                               console.log('phantom listing on 
port' + backendPort);
+                                               state = READY;}
+                                               ,500);  
+                               } else {
+                                       console.log('igore old startup:' + 
data);
+                               }
+                       }});
+               backend.stdout.on('data', function (data) {
+                       if (/committing/.test(data)) {
+                               var pattern = /\d+/;
+                               var port = parseInt(data.match(pattern));
+                               if (state == READY && port == backendPort ){
+                                       state = STOPREQUEST;
+                                       console.log('phantom died at port 
'+port);
+                                       stopBackend();
+                               } else {
+                                       console.log('igore old shutdown: ' 
+data+ ' instead of '+ backendPort);
+                               }
+                       }
+               });
+       }
 };
-startBackend();
+var stopBackend = function (){
+       if (state == STOPREQUEST){
+               state = STOPPING;
+               backend.kill();
+               backendPort=0;
+               backend = null;
+               state = STOPPED;
+       }
+};
 
+startBackend();
+var restartBackend = function(){
+       stopBackend();
+       state = START_REQUEST;
+       startBackend();
+};
 /* -------------------- Web service --------------------- */
 
 
@@ -94,7 +154,7 @@
 };
 
 
-function handleRequest(req, res, tex) {
+function handleRequest(req, res, tex, oldPort) {
        // do the backend request
        var query = new Buffer(querystring.stringify({tex:tex})),
                options = {
@@ -111,6 +171,7 @@
                };
        var chunks = [];
        //console.log(options);
+
        var httpreq = http.request(options, function(httpres) {
                httpres.on('data', function(chunk) {
                        chunks.push(chunk);
@@ -127,31 +188,56 @@
                        requestQueue.shift();
                        handleRequests();
                });
-       });
-       httpreq.on('error', function(err) {
-               console.log('error', err.toString());
-               res.writeHead(500);
-               return res.end(JSON.stringify({error: "Backend error: " + 
err.toString()}));
+               httpres.on('error', function(err) {
+                       if ( backendPort == oldPort ){
+                               if (state == READY){
+                                       state = STOPREQUEST;
+                                       restartBackend();
+                               }
+                       }
+                       console.log(' http error', err.toString());
+                       res.writeHead(500);
+                       return res.end(JSON.stringify({sucess:false,error: 
"Backend error: " + err.toString()}));
+               });
        });
 
+       httpreq.setTimeout(200); 
+
        httpreq.end(query);
+
 }
 
 app.post(/^\/$/, function ( req, res ) {
        // First some rudimentary input validation
        if (!req.body.tex) {
-               res.writeHead(400);
-               return res.end(JSON.stringify({error: "'tex' post parameter is 
missing!"}));
+               res.writeHead(200);
+               return res.end(JSON.stringify({sucess:false,error: "'tex' post 
parameter is missing!"}));
        }
        var tex = req.body.tex;
-
-       requestQueue.push(handleRequest.bind(null, req, res, tex));
-       // phantomjs only handles one request at a time. Enforce this.
-       if (requestQueue.length === 1) {
+       console.log('getting'+tex);
+       console.log('readystate:'+state+' restarts: '+restarts );
+       //if ( ! ready ){       setTimeout(function(){console.log('oha');},100) 
}
+       if ( state == READY ){
+               console.log('ready');
+               requestQueue.push(handleRequest.bind(null, req, res, tex, 
backendPort));
+               // phantomjs only handles one request at a time. Enforce this.
+               if ( requestQueue.length === 1) {
                // Start this process
                handleRequests();
+               }
+       } else if ( state === STOPPED ){
+               state = START_REQUEST;
+               startBackend();
+               return res.end(JSON.stringify({sucess:false, error: "Backend 
stopped...trying to restart"}));
+       } else if( state == STARTING) {
+               setTimeout(function(){
+                       if(state == STARTING){
+                       state = STOPPED;
+                       }}, 2000);
+                               return res.end(JSON.stringify({sucess:false, 
error: "Backend is starting"+state+"...try again later: "}));
+       } else {
+               return res.end(JSON.stringify({sucess:false, error: "Backend in 
state"+state+"...try again later: "}));
        }
-
 });
 
 
diff --git a/mathoid/mathoid.js b/mathoid/mathoid.js
index a1a4688..9d2a69d 100755
--- a/mathoid/mathoid.js
+++ b/mathoid/mathoid.js
@@ -12,7 +12,7 @@
        // long-running request would otherwise hold up all concurrent short 
requests.
        var numCPUs = require('os').cpus().length + 3;
        // Fork workers.
-       for (var i = 0; i < numCPUs; i++) {
+       for (var i = 0; i < 1; i++) {
                cluster.fork();
        }
 

-- 
To view, visit https://gerrit.wikimedia.org/r/87699
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If1d5ce7cf40932f9136f20fc3d06466cc67128d3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Math
Gerrit-Branch: master
Gerrit-Owner: Physikerwelt <w...@physikerwelt.de>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to