javascript - proyecto - Nodo js obtiene y configura datos de diferentes procesos.
servidor node js con express (5)
Tengo una aplicación de nodo que realizó un spawn (proceso secundario) y una aplicación, la aplicación tiene host y puerto:
var exec = require(''child_process'').spawn;
var child = exec(''start app'');
console.log("Child Proc ID " + child.pid)
child.stdout.on(''data'', function(data) {
console.log(''stdout: '' + data);
});
child.stderr.on(''data'', function(data) {
console.log(''stdout: '' + data);
});
child.on(''close'', function(code) {
console.log(''closing code: '' + code);
});
algunas aplicaciones se iniciarán de inmediato y otras demorarán entre 10 y 20 segundos hasta que se inicien .
Ahora uso el nodo http proxy para ejecutar la aplicación y el problema es que estoy obteniendo un error cuando el uso desea ejecutar la aplicación antes de que esté funcionando. ¿Alguna idea de cómo de alguna manera puedo resolver este problema?
proxy.on(''error'', function (err, req, res) {
res.end(''Cannot run app'');
});
Por cierto, no puedo enviar la respuesta 500 en error de proxy debido a la limitación de nuestro marco. Cualquier otra idea de cómo puedo rastrear la aplicación tal vez con algún tiempo de espera para ver si el tiempo envía una respuesta 200.
ACTUALIZACIÓN - Muestra de mi lógica.
httpProxy = require(''http-proxy'');
var proxy = httpProxy.createProxyServer({});
http.createServer(function (req, res) {
console.log("App proxy new port is: " + 5000)
res.end("Request received on " + 5000);
}).listen(5000);
function proxyRequest(req, res) {
var hostname = req.headers.host.split(":")[0];
proxy.web(req, res, {
target: ''http://'' + hostname + '':'' + 5000
});
proxy.on(''error'', function (err, req, res) {
res.end(''Cannot run app'');
});
}
¿Por qué no usar el emisor de eventos o mensajero?
var eventEmitter = require(''event-emitter'')
var childStart = require(''./someChildProcess'').start()
if (childStart !== true) {
eventEmitter.emit(''progNotRun'', {
data: data
})
}
function proxyRequest(req, res) {
var hostname = req.headers.host.split(":")[0];
proxy.web(req, res, {
target: ''http://'' + hostname + '':'' + 5000
});
eventEmitter.on(''progNotRun'', function(data) {
res.end(''Cannot run app'', data);
})
}
Lo que necesita es escuchar la primera respuesta en su proxy y mirar su código de estado para determinar si su aplicación se inició con éxito o no. Así es como haces eso:
proxy.on(''proxyRes'', function (proxyRes, req, res) {
// Your target app is definitely up and running now because it just sent a response;
// Use the status code now to determine whether the app started successfully or not
var status = res.statusCode;
});
Espero que esto ayude.
No estoy seguro de que entiendo la pregunta correctamente, pero ¿desea esperar a que un proceso secundario gire en la solicitud y desea que esta solicitud espere este proceso secundario y luego se le envíe? Si es así, una solución simple será usar algo como esto.
var count = 0;//Counter to check
var maxDelay = 45;//In Seconds
var checkEverySeconds = 1;//In seconds
async.whilst(
function () {
return count < maxDelay;
},
function (callback) {
count++;
self.getAppStatus(apiKey, function (err, status) {
if (status != 200) {
return setTimeout(callback, checkEverySeconds * 1000);
}
continueWithRequest();
});
},
function (err) {
if (err) {
return continueWithRequest(new Error(''process cannot spin!''));
}
}
);
La función continue con la solicitud () reenviará la solicitud al proceso hijo y getAppStatus devolverá 200 cuando el proceso hijo se haya iniciado y algún otro código cuando no lo esté. La idea general es que si bien comprobará cada segundo si el proceso se está ejecutando y después de 45 segundos, si no, devolverá un error. El tiempo de espera y los intervalos de verificación se pueden ajustar fácilmente. Esto es un poco burdo, pero funcionará para retrasar la solicitud y setTimeout iniciará una nueva pila y no se bloqueará. Espero que esto ayude.
No estoy seguro de si tiene sentido, en su aplicación principal, la experiencia debe comenzar con una página html y cada proceso secundario debe tener su propio cargador.
Básicamente, necesita un controlador http, que demora la solicitud hasta que el proceso hijo esté listo. Así que solo haga una llamada ajax desde el html y muestre la animación de carga hasta que el servicio esté listo.
//Ajax call for each process and update the UI accordingly
$.get(''/services/status/100'').then(function(resp) {
$(''#service-100'').html(resp.responseText);
})
//server side code (express syntax)
app.get(''/services/status/:id '', function(req,res) {
// Check if service is ready
serviceManager.isReady(req.params.id, function(err, serviceStats) {
if(err) {
//do logic err here , maybe notify the ui if an error occurred
res.send(err);
return;
}
// notify the ui , that the service is ready to run , and hide loader
res.send(serviceStats);
});
})
Si sabe (aproximadamente) cuánto tiempo tarda la aplicación en ponerse en marcha, simplemente agregue setTimeout(proxyRequest, <Time it takes the app to start in MS>)
(Probablemente hay soluciones más inteligentes / complicadas, pero esta es la más fácil).