In alcuni script Node.js che ho scritto, noto che anche se l'ultima riga è una chiamata sincrona, a volte non viene completata prima del nodo. js esce.Node.js socket.send() funzioni che non si completano prima dell'uscita
Non ho mai visto un'istruzione console.log
non eseguita/completata prima di uscire, ma ho visto che alcune altre istruzioni non sono state completate prima di uscire e credo che siano tutte sincrone. Potevo capire perché il callback di una funzione asincrona non avrebbe funzionato, naturalmente, in questo caso.
Il codice in questione è uno ZeroMQ .send()
chiamata in questo modo:
var zmq = require('zmq');
var pub = zmq.socket('pub');
pub.bindSync('tcp://127.0.0.1:5555');
setInterval(function(){
pub.send('polyglot');
},500);
Il codice qui sopra funziona come previsto ... ma se tolgo setInterval()
e basta chiamare in questo modo:
var zmq = require('zmq');
var pub = zmq.socket('pub');
pub.bindSync('tcp://127.0.0.1:5555');
pub.send('polyglot'); //this message does not get delivered before exit
process.exit(0);
... Quindi il messaggio non verrà consegnato - il programma apparentemente uscirà prima che la chiamata pub.send()
venga completata.
Qual è il modo migliore per garantire che una dichiarazione venga completata prima di uscire in Node.js? I ganci di spegnimento funzionerebbero qui, ma temo che sarebbe solo mascherare il problema dal momento che non è possibile mettere tutto ciò che è necessario per garantire corre in un gancio di arresto.
Questo problema può anche essere dimostrato in questo modo:
if (typeof messageHandler[nameOfHandlerFunction] == 'function') {
reply.send('Success');
messageHandler[nameOfHandlerFunction](null, args);
} else {
reply.send('Failure'); //***this call might not complete before the error is thrown below.***
throw new Error('SmartConnect error: no handler for ZMQ message sent from Redis CSV uploader.');
}
Credo che questo sia un/problema serio legit perché un sacco di programmi solo bisogno di pubblicare messaggi e poi morire, ma come possiamo efficacemente garantire tutto i messaggi vengono inviati (anche se non necessariamente ricevuti)?
EDIT: One (potenziale) modo per risolvere questo problema è quello di fare:
socket.send('xyz');
socket.close(); // supposedly this will block until the above message is sent
process.exit(0);
in base alla progettazione uno script sincrono verrà eseguito fino al completamento a meno di processo.exit() viene chiamato, quindi in questo caso dovrai mostrare del codice. Altrimenti sarà solo una supposizione di lavoro su qualcosa che potrebbe anche non essere vero. –
Non è possibile garantire il completamento asincrono in un hook di chiusura. – SLaks
potresti provare a metterlo in un setTimeout con 0? –