Salut à tous :)
J'aimerais savoir s'il y a un moyen de déporter une tâche en background sur NodeJS ?
Je m'explique : J'ai un script qui top 100% du CPU du serveur à certains moments (plus de 10 000 000 de lignes à agréger), du coup j'aimerais déporter ce processus dans un processus enfant et distinct afin d'éviter de bloquer (enfin ralentir à mort plutôt) le serveur pendant ce temps, mais je ne trouve pas de moyen 'simple' de le faire.
Donc si vous avez des solutions ou des outils à me proposer, je suis preneur.
Merci.
J'ai fait différemment du coup : j'ai créé une nouvelle VM sur laquelle je déporte les traitements lourds et/ou longs (via une simple requête HTTP, avec la lib node-rest-client), cela évite d'impacter la VM de l'app principale. Je suis conscient que cette solution ne peut pas être implémentée partout, cela étant, si on peut le faire, il ne faut pas hésiter.
Salut,
Si 100% du CPU est pris, ça ne va rien changer si tu le mets dans un autre processus, non ?
@tleb Beh disons qu'en le déportant dans un process child, ça permet au système de gérer les ressources allouées à chaque process, du coup essayer d'avoir du 50-50 ou au moins du 75-25 quoi ^^
@tleb J'ai essayé mais pas moyen de le faire fonctionner.. je n'arrive pas à faire communiquer le process master avec le child.
Tu peux utiliser,
var child = require('child_process').fork('./child', args);
Si tu veux communiquer avec le processus parent tu utilises process.send(code);
dans le processus child et tu écoutes avec
child.on('message', function(message) {
console.log(message)
});
dans le processus parent.
Quand le processus child se termine, cette event est déclenché dans le processus parent
child.on('close', function(code, signal) {
console.log('Child process ' + child.pid + ' exited with code ' + code);
});
Tu peux voir la doc pour d'autres events
Salut @sizo0,
Merci pour tes conseils, c'est exactement ce que j'ai fait.
Mais en fait j'ai l'impression que le process est kill juste après avoir été créé car je ne le vois pas dans ma liste de process node (j'utilise htop) :/
Il est peut-être kill puisqu'il n'y a rien à exécuter.
Tu peux me montrer le code parent et le code child.
master :
try {
var invoiceChildProcess = fork('./renderInvoice.js');
} catch (err) {
Utils.err(err, 'INVOICING::EXPLORE - INIT INVOICE CHILD PROCESS ERR');
}
try {
invoiceChildProcess.send({billingData: billingData});
} catch (err) {
Utils.err(err, 'INVOICING::EXPLORE - SEND DATA TO INVOICE CHILD PROCESS ERR');
}
invoiceChildProcess.on('uncaughtException', function (err) {
Utils.err(err.message + "\n" + err.stack);
});
invoiceChildProcess.on('message', function (inv) {
Utils.log('Receive invoice child process data :: ' + JSON.stringify(m), 'INVOICING::EXPLORE - RENDER INVOICE INTO CHILD PROCESS');
});
J'ai effacé le child, mais c'était un truc comme ça :
process.on('message', function (data) {
// code à exécuter
process.send('done');
});
Normalement le child ne doit pas être kill. Essaye de lancer cette commande pour voir s'il est vraiment kill
watch -n 1 -d "ps aux | grep [n]ode"
Pour la fonction send
, il faut un string en argument. Essaye donc de faire un JSON.stringify
.
Je ne comprends pas non plus pk tu mets des try { } catch { }
un peu partout.
Je te mets le code ci-dessous pour l'essayer et voir s'il marche pour toi.
Code parent.
var child_process = require('child_process');
var child = child_process.fork('./child');
send();
child.on('message', function (message) {
console.log(message);
setTimeout(function () {
send();
}, 1000);
});
child.on('close', function (code, signal) {
console.log('Child process' + child.pid + 'exited with code ' + code);
});
function send() {
child.send('message from parent');
}
Code child
process.on('message', function (message) {
console.log(message);
process.send('message from child');
});
Salut si tu veux actuellement je check un peu les process node tu peux regarder ce que j'ai mis sur mon github
https://github.com/dgpgdev/processcom
ça permet de creer un ou plusieurs process enfants et de communiquer avec. Si ça peut t'aider